2015-10-13 102 views
8

我试图使用AsyncTask类来获取网站的内容。 logcat反复告诉我W/art: Suspending all threads took: 15(or any other number)ms。我的应用程序被冻结,直到日志消息完成打印。 UI在日志完成后显示。我跟着一个教程,并重新检查我的代码应该与教程相同。过了一段时间,它从网站上记录了几行代码,但没有更多。我也尝试过不同的网站。这是我的AsyncTask:应用程序挂起并挂起所有线程,同时使用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(); 

     } 

    } 


} 

回答

15

下面一行是一个问题:

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

这句话的.get()部分的意思是 “等待,直到任务完成”。这在执行任务时有效地阻止了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/"); 
    } 


} 
+0

这种固定的应用程序冻结,但我仍然得到所有的“W /艺术:暂停所有线程:日志中的9.850ms“消息。我还得到:“I/art:背景部分并发标记扫描GC已释放58(2048B)AllocSpace对象,45(16MB)LOS对象,40%免费,21MB/36MB,暂停7.230ms总计23.895ms” –

+5

@EmilØgård这些各种消息对所有应用程序都很常见,您不应该担心。它们只是Android框架日志的一部分,用于诊断内存管理问题和调试问题。在几乎所有的应用程序中,它们都可以安全地忽略(并且无法摆脱它们)。 – adelphus

+2

更具体地说,“mark sweep GC”是报告垃圾回收器正在做什么来回收内存。 “暂停所有线程”消息是因为垃圾收集器执行其工作时,所有线程都必须暂停。这种特殊的扫描花费了大约24毫秒,或大约十分之一的眨眼。 ;-) – nasch

2

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

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

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

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

-4

我以这样的方式得到了同样的问题。 “而”是你的问题的原因,你需要摆脱它。

0

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

您有更好的选择AsyncTask

从“线程性能”文章developer.android.com

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

可以使用HandlerThread作为替代。如果你有很多的网址是牵强,去ThreadPoolExecutor

看一看相关博文:

Handler vs AsyncTask vs Thread