Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 独立线程上的网络相关任务_Java_Android_Multithreading - Fatal编程技术网

Java 独立线程上的网络相关任务

Java 独立线程上的网络相关任务,java,android,multithreading,Java,Android,Multithreading,我目前有一个spoly类,这是我编写的一个类,它使用JSoup库解析HTML。这里还显示了我的占位符片段类 public static class PlaceholderFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInst

我目前有一个spoly类,这是我编写的一个类,它使用JSoup库解析HTML。这里还显示了我的
占位符片段

    public static class PlaceholderFragment extends Fragment
    {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState)
        {
            final Button button = (Button) rootView.findViewById(R.id.button1);
            final TextView textview = (TextView) rootView.findViewById(R.id.textview1);

            button.setOnClickListener(new View.OnClickListener()
            {

                @Override
                public void onClick(View v)
                {
                    Pollen pollenObject = new Pollen(19104);
                    textview.setText(pollenObject.getCity());
                }
            });

            return rootView;
        }
    }
这是我的花粉课

public static class Pollen
{

    @SuppressLint("SimpleDateFormat")
    public Pollen(int zipcode)
    {
        this.zipcode = zipcode;
        Document doc;
        try
        {
            // pass address to 
            doc = Jsoup.connect("http://www.wunderground.com/DisplayPollen.asp?Zipcode=" + this.zipcode).get();

            // get "location" from XML
            Element location = doc.select("div.columns").first();
            this.location = location.text();

            // get "pollen type" from XML
            Element pollenType = doc.select("div.panel h3").first();
            this.pollenType = pollenType.text();

            SimpleDateFormat format = new SimpleDateFormat("EEE MMMM dd, yyyy");

            // add the four items of pollen and dates
            // to its respective list
            for(int i = 0; i < 4; i++)
            {
                Element dates = doc.select("td.text-center.even-four").get(i);
                Element levels = doc.select("td.levels").get(i);

                try
                {
                    pollenMap.put(format.parse(dates.text()), levels.text());
                }
                catch (ParseException e)
                {
                    e.printStackTrace();
                }
            }
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
这是一个
异步任务
。您必须使用
AsyncTask
执行所有网络操作。 它基本上有3种方法

  • onPreExecute()
  • doInBackground()
  • onPostExecute()
doInBackground()
方法中执行网络操作。更新
onPostExecute()中的UI


AsyncTask
是Android框架提供的一种机制,用于在不阻塞主UI线程的情况下促进长时间运行任务的执行。阅读Android开发者网站上的教程,了解关于这个主题的详细介绍

提供的链接应该可以帮助您使用
AsyncTask
机制重新设计类


希望这有帮助

是的,您试图在UI线程内进行非法联网,并捕获异常,该异常是
NetworkOnMainThreadException

您可以使用现在正在执行的
AsyncTask
,而不是在主线程内连接,但它不应该是抽象的,它只是一个普通类,因此您可以执行
AsyncTask

示例:

    public class RetrievePollenTask extends AsyncTask<Integer, Void, Pollen>
{

    protected Pollen doInBackground(String... params)
    {
        Pollen pollenObject = new Pollen(19104);
        return pollenObject;
    }

    protected void onPostExecute(Pollen result) {
         textview.setText(pollenObject.getCity());
     }

}
公共类RetrievePollenTask扩展异步任务
{
受保护花粉背景(字符串…参数)
{
花粉对象=新花粉(19104);
返回pollenObject;
}
受保护的void onPostExecute(结果){
setText(pollenObject.getCity());
}
}

可以将asynctask作为片段的内部类,这样就不需要在其上传递上下文参数。也不要将更新任何视图放在
doInBackground
中,因为它将捕获异常的线程不同。

一个
AsyncTask
用于在非UI线程中运行代码,但也有可以与UI交互的方法

AsyncTask

这定义了AsyncTask使用的对象。如果不使用任何对象,请使用
Void

  • 第一个是
    doInBackground()
    的输入
  • 第二个参数是
    onProgressUpdate()
    的参数,用于定期更新用户的进度
  • 最后一个是从
    doInBackground()返回的结果
这些参数是用
对象声明的。。。vars
实际上是可以使用
vars[index]
访问的数组。如果只传递一个变量,请使用
var[0]

类检索PollenTask扩展异步任务
{
@凌驾
受保护的void onPreExecute(){
//在*任务运行之前*在此处设置ProgressBar或其他UI操作
}
@凌驾
受保护花粉背景(字符串…参数)
{
//在此处执行单独的非UI线程操作
//调用publishProgress(int)定期更新UI
返回pollenObject;
}
@凌驾
受保护的void onProgesUpdate(整数…进度){
//更新用户界面或进度条
}
@凌驾
PostExecute上受保护的无效(已返回)
//在此再次返回UI线程以更新视图或取消进度条等
//这将在任务完成后*执行
//它从doInBackground()的返回中接收参数,因此您可以在更新UI时使用该参数。
}
}
经验法则:

  • 网络(或其他I/O或长时间运行)代码进入
    doInBackground()
    ,在后台线程中执行
  • UI代码进入
    onPostExecute()
    ,后台操作完成后,UI线程将立即执行该代码
在您的示例中,这可能是您可以编写的最简单的代码:

button.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick(View v)
    {
        AsyncTask<Integer, Void, Pollen> loadPollen = new AsyncTask<Integer, Void, Pollen>()
        {
            @Override
            protected Pollen doInBackground(Integer... params)
            {
                return new Pollen(params[0]);
            }

            @Override
            protected void onPostExecute(Pollen result)
            {
                textview.setText(result.getCity());
            }
        };

        loadPollen.execute(19104);
    }
});     
button.setOnClickListener(新视图.OnClickListener()
{
@凌驾
公共void onClick(视图v)
{
AsyncTask LoadPolen=新建AsyncTask()
{
@凌驾
受保护的doInBackground(整数…参数)
{
返回新花粉(参数[0]);
}
@凌驾
受保护的void onPostExecute(结果)
{
setText(result.getCity());
}
};
执行(19104);
}
});     

Hi Rod。非常感谢您的回复。我假设
RetrievePollenTask
在我的
Fragment
类中,对吗?如果不这样做,我就无法访问
textview
对象。@如果您将textview作为一个全局变量,这样您就可以通过内部类引用它,或者在Asynctask中创建一个构造函数,并将textview作为一个参数传递出去,我的天哪。非常感谢你。你解决了一个我花了三天时间才弄明白的问题。非常感谢你。你介意向我解释一下你是怎么决定做的吗?对不起,我不明白。。。您的意思是“关于使用AsyncTask”还是“关于此特定代码段”?请不要使用日志或代码的屏幕截图,请将日志和缩进/格式粘贴为代码。
button.setOnClickListener(new View.OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                RetrievePollenTask object = new RetrievePollenTask();
                object.execute(19104);
            }
        });
    public class RetrievePollenTask extends AsyncTask<Integer, Void, Pollen>
{

    protected Pollen doInBackground(String... params)
    {
        Pollen pollenObject = new Pollen(19104);
        return pollenObject;
    }

    protected void onPostExecute(Pollen result) {
         textview.setText(pollenObject.getCity());
     }

}
class RetrievePollenTask extends AsyncTask<String, Integer, Pollen>
{

    @Override
    protected void onPreExecute() {
        // set up a ProgressBar or other UI action here *before* the task runs
    }

    @Override
    protected Pollen doInBackground(String... params)
    {
        // perform your separate non UI thread actions here
        // call publishProgress(int) to update your UI periodically
        return pollenObject;
    }

    @Override
    protected void onProgessUpdate(Integer... progress) {
        // update your UI or ProgressBar
    }

    @Override
    protected void onPostExectute(Pollen resultReturned)
        // back to the UI thread again here to update Views or cancel your ProgressBar etc
        // this executes *after* your task has completed
        // it receives its argument from the return of doInBackground() so you can use that when updating your UI.
    }
}
button.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick(View v)
    {
        AsyncTask<Integer, Void, Pollen> loadPollen = new AsyncTask<Integer, Void, Pollen>()
        {
            @Override
            protected Pollen doInBackground(Integer... params)
            {
                return new Pollen(params[0]);
            }

            @Override
            protected void onPostExecute(Pollen result)
            {
                textview.setText(result.getCity());
            }
        };

        loadPollen.execute(19104);
    }
});