Pracuję nad małą aplikacją, która czyta na konkretnych stronach HTML, ponownie je formatuje, a następnie wyświetla w WebView. Jeśli uruchomię swój kod w wątku GUI, wydajność jest prawie nieistotna w porównaniu do tego, że po prostu pozwala to WebView pokazać oryginalną stronę html. Ale jeśli jestem dobrym chłopcem i lubię, jak mi powiedziano, mam użyć AsyncTask, aby uruchomić kod w tle, aby nie zamrozić GUI w ciągu tych 3-5 sekund, w których mój kod wykonuje swoją pracę . Problem polega na tym, że jeśli to zrobię, wykonanie kodu zajmie więcej niż 10 razy. Wyświetlenie strony trwa 60 lub więcej sekund, co jest niedopuszczalne.AsyncTask, czy musi przyjąć takie trafienie karne?
Śledzenie problemu, TraceView pokazuje mi, że moja AsyncTask jest (domyślnie priorytetem) działa w porach około 10 ms, około 4 razy na sekundę. Muszę ustawić priorytet mojego wątku na MAX_PRIORITY, aby zbliżyć się do akceptowalnego czasu ładowania, ale nawet wtedy trwa to 3-4 razy dłużej niż w przypadku uruchamiania w wątku GUI.
Czy robię coś nie tak, czy to tak po prostu działa? I czy to musi działać w ten sposób ...?
Oto kod compilable na żądanie:
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...
}
}
Aby uruchomić dokładnie ten sam kod w mojej klasie FilterX gdy uruchamiane jako AsyncTask jak wtedy, gdy są wykonywane w wątku GUI, rozebrałem wszystko ProgressBar rzeczy, a potem uzyskać następujące czasy:
- 30+ sekund, aby załadować stronę w domyślnym priorytetem wątku
- 15+ sekund, aby załadować stronę na MAX_PRIORITY
- 5+ sekund, aby załadować stronę kiedy uruchomić w wątku GUI
Gdzie TraceView twierdzi, że spędzasz większość swojego czasu podczas korzystania z asynchronicznego zadania? Przechodzenie od 5 sekund do 60 powoduje, że brzmi to jak coś poszło strasznie źle, po refaktoryzacji kodu. (w razie potrzeby wstawiaj odpowiednie fragmenty) – smith324
Nie ma prawdziwego "ponownego faktoringu". Po prostu usuwam wywołanie execute() i zamiast tego wołam doInBackground() z wątku GUI. Wytnę odpowiednie części i pokażę wam, jego trywialne rzeczy i bardzo wątpię, że to jest jakikolwiek problem. – OppfinnarJocke
Nigdy nie odpowiedziałeś na moje pierwsze pytanie: gdzie TraceView mówi, że używasz swojego czasu? – smith324