应用程序在使用AsyncTask时挂起并挂起所有线程

时间:2015-10-13 23:03:40

标签: java android multithreading

我正在尝试使用AsyncTask类来获取网站的内容。 logcat反复告诉我W/art: Suspending all threads took: 15(or any other number)ms。我的应用程序被冻结,直到日志消息完成打印。日志完成后,UI会显示。我按照教程进行了双重检查,我的代码应与教程相同。过了一会儿,它会从网站上记录几行代码,但仅此而已。我也尝试过不同的网站。这是我的AsyncTask:

public class MainActivity extends AppCompatActivity {

    public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {

            String result = "";
            URL url;
            HttpURLConnection urlConnection = null;

            try {

                url = new URL(urls[0]);

                urlConnection = (HttpURLConnection) url.openConnection();

                InputStream in = urlConnection.getInputStream();

                InputStreamReader reader = new InputStreamReader(in);

                int data = reader.read();

                while (data != -1) {

                    char current = (char) data;

                    result += current;

                    data = reader.read();

                }

                return result;

            } catch (Exception e) {

                e.printStackTrace();

            }

            return null;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        String result = null;

        try {

            result = task.execute("http://www.vg.no/").get();

            Log.i("URL content" , result);

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (ExecutionException e) {

            e.printStackTrace();

        }

    }


}

4 个答案:

答案 0 :(得分:15)

以下行是一个问题:

result = task.execute("http://www.vg.no/").get();

此声明的.get()部分表示&#34;等待任务完成&#34;。这有效地阻止了任务执行时的UI线程。

让后台任务执行其操作并通过onPostExecute()获取任何结果。查看以下AsyncTask:

public class MainActivity extends AppCompatActivity {

   public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {
            ...
        }

        @Override
        protected void onPostExecute(String result) {
            Log.i("URL content" , result);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        task.execute("http://www.vg.no/");
    }


}

答案 1 :(得分:2)

首先,我认为你误用了AsyncTask。 AsyncTask应该异步使用,而不是使用get()。

同步

你应该在AsyncTask中添加onPostExecute并在那里得到结果。

protected void onPostExecute(String result) {
     //You could get the result here
}

你可以在这里阅读更好的教程 - &gt; http://developer.android.com/reference/android/os/AsyncTask.html

答案 2 :(得分:2)

  

我正在尝试使用AsyncTask类来获取网站的内容。 logcat告诉我W / art:暂停所有线程:15(或任何其他数字)ms重复。

您可以更好地替代AsyncTask

来自developer.android.com的“线程效果”文章:

  

使用AsyncTask时,需要记住一些重要的性能方面。首先,默认情况下,应用程序将其创建的所有AsyncTask对象推送到单个线程中。因此,它们以串行方式执行,并且 - 与主线程一样 - 特别长的工作包可以阻塞队列。因此,我们建议您仅 使用AsyncTask来处理持续时间小于5毫秒的工作项。

您可以使用HandlerThread作为替代方案。如果您要提取多个网址,请转到ThreadPoolExecutor

查看相关帖子:

Handler vs AsyncTask vs Thread

答案 3 :(得分:-4)

我以这种方式遇到了同样的问题。 &#34;而&#34;是你的问题的原因,你需要摆脱它。