2015-10-13 48 views
8

Tôi đang cố gắng sử dụng lớp học AsyncTask để nhận nội dung của trang web. Các logcat nói với tôi W/art: Suspending all threads took: 15(or any other number)ms nhiều lần. Ứng dụng của tôi bị đóng băng cho đến khi thông báo tường trình được in xong. Giao diện người dùng hiển thị sau khi nhật ký được thực hiện. Tôi đã làm theo một hướng dẫn và đã kiểm tra kỹ xem mã của tôi có giống với hướng dẫn hay không. Sau một thời gian, nó ghi lại một vài dòng mã từ trang web, nhưng không có gì hơn. Tôi đã thử với các trang web khác nhau. Dưới đây là AsyncTask tôi:Ứng dụng bị treo và treo tất cả các chủ đề khi sử dụng 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(); 

     } 

    } 


} 

Trả lời

15

Các dòng sau là một vấn đề:

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

Các .get() phần của tuyên bố này có nghĩa là "đợi cho đến khi nhiệm vụ hoàn thành". Điều này có hiệu quả chặn chuỗi giao diện người dùng trong khi tác vụ thực thi.

Chỉ để tác vụ nền thực hiện nội dung của nó và nhận lại bất kỳ kết quả nào qua onPostExecute(). Hãy xem AsyncTask sau:

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

này cố định đóng băng ứng dụng, nhưng tôi vẫn nhận được tất cả các: "W/nghệ thuật: Đình chỉ tất cả các chủ đề mất: 9.850ms "thư trong nhật ký. Tôi cũng nhận được điều này: "Tôi/nghệ thuật: Nền một phần đồng thời quét GC giải phóng 58 (2048B) đối tượng AllocSpace, 45 (16MB) LOS đối tượng, 40% miễn phí, 21MB/36MB, tạm dừng 7.230ms tổng 23.895ms" –

+5

@ EmilØgård các loại tin nhắn là phổ biến cho tất cả các ứng dụng và bạn không nên quan tâm. Chúng chỉ đơn giản là một phần của việc ghi nhật ký khung công tác của Android và được sử dụng để chẩn đoán các vấn đề quản lý bộ nhớ và các vấn đề gỡ lỗi. Trong hầu hết các ứng dụng, chúng có thể được bỏ qua một cách an toàn (và bạn không thể loại bỏ chúng). – adelphus

+2

Cụ thể hơn, điều "quét GC đánh dấu" là báo cáo những gì các nhà sưu tập rác đang làm để đòi lại bộ nhớ. Các "đình chỉ tất cả các chủ đề" tin nhắn là bởi vì tất cả các chủ đề phải được đình chỉ khi thu gom rác làm công việc của mình. Việc quét đặc biệt này mất khoảng 24 phần nghìn giây, hoặc khoảng một phần mười của một chớp mắt. ;-) – nasch

2

Trước hết tôi nghĩ bạn đã sử dụng sai AsyncTask. AsyncTask nên được sử dụng không đồng bộ không đồng bộ bằng cách sử dụng get().

bạn nên thêm onPostExecute vào trong AsyncTask và nhận kết quả ở đó.

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

Bạn có thể đọc hướng dẫn tốt hơn ở đây -> http://developer.android.com/reference/android/os/AsyncTask.html

-4

Tôi có cùng một vấn đề theo cách như vậy. "trong khi" là lý do của vấn đề của bạn, bạn cần phải loại bỏ nó.

0

Tôi đang cố gắng sử dụng lớp AsyncTask để nhận nội dung của trang web. Các logcat nói với tôi W/nghệ thuật: Đình chỉ tất cả các chủ đề đã: 15 (hoặc bất kỳ số nào khác) ms nhiều lần.

Bạn có thể thay thế tốt hơn để AsyncTask.

Từ "Threading Performance" bài báo của developer.android.com:

Khi sử dụng AsyncTask, có một vài khía cạnh hiệu suất quan trọng cần lưu ý. Đầu tiên, theo mặc định, một ứng dụng sẽ đẩy tất cả các đối tượng AsyncTask mà nó tạo ra thành một chuỗi duy nhất. Do đó, chúng thực thi theo kiểu nối tiếp, và — như với luồng chính — một gói công việc đặc biệt dài có thể chặn hàng đợi. Vì lý do này, chúng tôi khuyên bạn chỉ nên sử dụng sử dụng AsyncTask để xử lý các mục công việc ngắn hơn 5 mili giây.

Bạn có thể sử dụng HandlerThread làm phương án thay thế.Nếu bạn có nhiều URL để được lấy, đi cho ThreadPoolExecutor

Hãy nhìn vào bài liên quan (s):

Handler vs AsyncTask vs Thread

Các vấn đề liên quan