java - 单独线程上的网络相关任务

标签 java android multithreading

我目前有一个 Pollen 类,它是我编写的一个类,它使用 JSoup 库来解析 HTML。这里还显示了我的 PlaceholderFragment 类。

    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;
        }
    }

这是我的花粉类(class)。

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();
        }
    }
}

虽然每次尝试都失败了,但我学到了很多东西。我发现,在使用 onClick 中调用 Pollen 类时,我正在执行一项昂贵的任务。因此,我应该把它放在一个单独的线程中。另外,由于我在主/UI 线程中调用 Pollen 类,因此它会导致我的应用程序崩溃。

我查阅了这个 Stackoverflow 问题来帮助我尝试解决我的问题:How to fix android.os.NetworkOnMainThreadException?

我通过 logcat 中的错误日志发现了我的错误和解决方案,特别是 NetworkOnMainThread,其中 Android 明确阻止我在 UI 线程上执行任何网络操作。

我的问题是 - 如何将我的 Pollen 类分配到不在我的 UI 类中的单独线程中?

enter image description here

继续我关于 Stackoverflow 线程的教程,我添加了此类。我不知道我在做什么..但我会尽力继续:

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

    protected Pollen doInBackground(String... params)
    {
        // TODO Auto-generated method stub
        return null;
    }

}

最佳答案

是的,您正在尝试在 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());
     }

}

您可以将异步任务作为 fragment 的内部类,这样您就不需要在其上传递上下文参数。另外,不要将更新任何 View 放入 doInBackground 中,因为它是一个不同的线程,它将捕获异常。

关于java - 单独线程上的网络相关任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23973612/

相关文章:

java - 如何使用另一个堆栈反转java中的堆栈?

android - ObjectAnimator 忽略 LayoutTransition 中的持续时间

c++ - 来自主线程的 VTK 窗口线程,C++

PHP pthreads - 共享对象

java - 元标记中的 JSF 重定向

Java,字符串的运算符重载和 "+"运算符

java - Thymeleaf:通过错误代码显示全局错误

android - 无需 root 即可读写根文件夹

android - 如何更正 'Instrumentation run failed due to ' java.lang.IllegalArgumentException''

Android 服务、线程和 UI