Tôi đang phát triển một ứng dụng nhỏ đọc trong các trang html cụ thể, định dạng lại chúng và sau đó hiển thị chúng trong một WebView. Nếu tôi chạy mã của tôi trong chủ đề GUI, hiệu suất đạt gần như không đáng kể so với việc chỉ cho phép WebView hiển thị trang html gốc. Nhưng nếu tôi là một cậu bé tốt và làm như tôi đã nói, tôi phải sử dụng một AsyncTask để chạy mã trong nền để không đóng băng GUI trong 3-5 giây mã của tôi thực hiện công việc của mình . Vấn đề là ... nếu tôi làm như vậy, mã sẽ mất hơn 10 lần để hoàn thành. Một trang mất hơn 60 giây để hiển thị, điều này là không thể chấp nhận được.AsyncTask, phải mất một cú đánh phạt hiệu suất như vậy ...?
Theo dõi vấn đề, TraceView cho tôi thấy AsyncTask của tôi là (ưu tiên mặc định) chạy trong khoảng 10 ms khối, khoảng 4 lần mỗi giây. Tôi cần đặt mức độ ưu tiên của luồng thành MAX_PRIORITY để gần với thời gian tải có thể chấp nhận được, nhưng thậm chí sau đó phải mất 3-4 lần so với khi tôi chạy trong luồng GUI.
Tôi có làm điều gì sai, hay đây chỉ là cách nó hoạt động? Và nó phải hoạt động theo cách này ...?
Đây là mã biên dịch được theo yêu cầu:
package my.ownpackage.athome;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class AndroidTestActivity extends Activity
{
WebView webview;
//...
private class HelloWebViewClient extends WebViewClient
{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
AndroidTestActivity.this.fetch(view, url);
return true;
}
}
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// To allow to connect to the web and pull down html-files, reset strict mode
// see http://stackoverflow.com/questions/8706464/defaulthttpclient-to-androidhttpclient
if (android.os.Build.VERSION.SDK_INT > 9)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
// webview init etc...
fetch(webview, "http://www.example.com");
}
// This one calls either the AsyncTask or does it all manually in the GUI thread
public void fetch(WebView view, String url)
{
//** Use these when run as AsyncTask in background - SLOW!
//** Takes 30+ seconds at default thread priority, with MAX_PRIORITY 15+ seconds
// AsyncTask<Void, String, String> fx = new FilterX(url, view, this);
// fx.execute(); // running as AsyncTask takes roughly ten times longer than just plain load!
//** Use these when not running as AsyncTask - FAST! takes ~5 seconds
FilterX fx = new FilterX(url, view, this);
fx.onPreExecute();
final String str = fx.doInBackground();
fx.onPostExecute(str);
}
}
class FilterX extends AsyncTask<Void, String, String>
{
WebView the_view = null;
// other stuff...
FilterX(final String url, final WebView view, final Activity activity)
{
the_view = view;
// other initialization
// same code in both cases
}
protected void onPreExecute()
{
// same code in both cases
}
protected String doInBackground(Void... v)
{
// same in both cases...
return new String(); // just to make it compile
}
protected void onPostExecute(final String string)
{
the_view.loadUrl(string);
// same in both cases...
}
}
Để chạy chính xác cùng mã trong lớp FilterX của tôi khi chạy như AsyncTask như khi chạy trên thread GUI, tôi tước tất cả những thứ ProgressBar, và sau đó tôi có được timings sau:
- 30+ giây để tải một trang ở mức ưu tiên chủ đề mặc định
- 15+ giây để tải một trang tại MAX_PRIORITY
- 5+ giây để tải trang khi chạy trong chủ đề GUI
TraceView nói bạn đang dành phần lớn thời gian của mình khi sử dụng tác vụ không đồng bộ? Đi từ 5 giây đến 60 làm cho nó nghe như một cái gì đó đã đi sai lầm khủng khiếp khi bạn refactored mã của bạn. (đăng các đoạn mã có liên quan nếu cần) – smith324
Không thực sự "tái bao thanh toán" xảy ra. Tôi chỉ cần loại bỏ lệnh gọi execute() và thay vào đó gọi doInBackground() từ luồng GUI. Tôi sẽ đọc các phần liên quan và cho bạn thấy, những điều nhỏ nhặt của nó và rất nghi ngờ rằng đây là vấn đề. – OppfinnarJocke
Bạn chưa bao giờ trả lời câu hỏi đầu tiên của tôi: TraceView nói bạn đang sử dụng thời gian của bạn ở đâu? – smith324