AsyncTask, должно ли это иметь такое снижение производительности…?

Я разрабатываю небольшое приложение, которое читает определенные html-страницы, переформатирует их, а затем показывает их в WebView. . Если я запускаю свой код в потоке графического интерфейса пользователя, снижение производительности будет почти незначительным по сравнению с простым разрешением WebView отображать исходную html-страницу. Но если я хороший мальчик и поступаю так, как мне говорят, я должен использовать AsyncTask для запуска кода в фоновом режиме, чтобы не замораживать графический интерфейс в течение этих 3-5 секунд, мой код выполняет свою работу. . Проблема в том, что ... если я это сделаю, код будет продолжаться более чем в 10 раз дольше. Страница отображается не менее 60 секунд, что недопустимо.

Отслеживая проблему, TraceView показывает мне, что моя AsyncTask (с приоритетом по умолчанию) выполняется фрагментами примерно по 10 мс, примерно 4 раза в секунду. Мне нужно установить приоритет моего потока на MAX_PRIORITY, чтобы приблизиться к приемлемому времени загрузки, но даже в этом случае это занимает в 3-4 раза больше времени, чем при запуске в потоке графического интерфейса.

Я что-то делаю не так, или это просто так? И должно так работать ...?

Вот компилируемый код в соответствии с запросом:

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...
    }
}

Чтобы запустить точно тот же код в моем классе FilterX при запуске как AsyncTask, как и при запуске в потоке графического интерфейса, я удалил весь материал ProgressBar, а затем я получить следующие тайминги:

  • 30+ секунд для загрузки страницы с приоритетом потока по умолчанию
  • 15+ секунд для загрузки страницы с MAX_PRIORITY
  • 5+ секунд для загрузки страницы при запуске в потоке графического интерфейса
29
задан Tamás 6 September 2012 в 19:08
поделиться