2015-10-13 73 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