AsyncTask не запускается при следующем вызове Activity - PullRequest
1 голос
/ 23 января 2012

На моем экране-заставке Activity я выполняю некоторые длительные инициализации.Поэтому я создаю фоновую асинхронную задачу и выполняю ее, чтобы выполнить тяжелую работу.Затем основной поток Activity (UI) отображает изображение заставки и возвращается из метода onCreate (), который вызывает обновление экрана.Когда асинхронная задача завершается, она вызывает метод на активности заставки, который вызывает основное действие и завершает себя.

Это прекрасно работает при первом запуске приложения.Если я завершаю работу приложения, а затем перезапускаю его, создается совершенно новая асинхронная задача, и когда вызывается метод execute, вызывается метод onPreExecute (), но метод doInBackground () никогда не вызывается при втором запуске.

Если я использую диспетчер задач, чтобы принудительно убить приложение, то оно работает правильно.Эта проблема возникает, когда приложение завершено (показан домашний экран устройства), но ОС еще не восстановлена.

Я создаю новый объект Async Task и проверяю, не отменено ли оно до вызова execute() метод.Как будто Async Task запоминает предыдущий экземпляр и не запускает новую Async Task, потому что думает, что она уже выполнена один раз.

Почему совершенно новая Async Task не вызывает метод doInBackground () при выполненииназывается?

Код асинхронной задачи:

public class AsynchTaskInitializeApplication extends AsyncTask<Void, Integer, Boolean> {

    private ActivitySplashScreen theActivity;

    public AsynchTaskInitializeApplication() {
            Log.d("App", "AsynchTaskInitializeApplication constructor called\n");
    }

    public void setTheActivity(ActivitySplashScreen theActivity) {
            Log.d("App", "AsynchTaskInitializeApplication::setTheActivity() called\n");
            this.theActivity = theActivity;
    }

    @Override
    protected Boolean doInBackground(Void... arg0) {
            boolean result = false;

            Log.d("App", "AsynchTaskInitializeApplication::doInBackground() called\n");

            try {
                    // Initialization code goes here
                    result = true;
            } catch (Exception e) {
                    // Something went wrong - we failed.
                    // Return false result.
                    e.printStackTrace();
            }

            return result;
    }

    @Override
    protected void onPreExecute() {
            super.onPreExecute();
            Log.d("App", "AsynchTaskInitializeApplication::onPreExecute() called\n");
    }

    @Override
    protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);

            if (this.theActivity != null) {
                    this.theActivity.initializationComplete(result);
            }
    }
}

Код создания / вызова:

    // Start the asynchronous task that starts the data store and does
    // any other heavy hitting initialization.
    this.mBackgroundInitialization = null;
    this.mBackgroundInitialization = new AsynchTaskInitializeApplication();
    this.mBackgroundInitialization.setTheActivity(this);
    Log.d("App", "ActivitySplashScreen::onCreate() start the background initialization\n");
    if (this.mBackgroundInitialization.isCancelled()) {
            Log.d("App", "ActivitySplashScreen::onCreate() background initialization task already cancelled\n");
    }       
    this.mBackgroundInitialization.execute();
    Log.d("App", "ActivitySplashScreen::onCreate() background initialization should have started\n");

Код, который вызывается при завершении фоновой задачи:

    public void initializationComplete(boolean readyToGo) {
    Log.d("App", "Initialization is complete " + readyToGo + "\n");
    // Attempt to forcibly stop the background task.
    // A second attempt to run the app does not cause it to execute. 
    if (!this.mBackgroundInitialization.isCancelled()) {
            this.mBackgroundInitialization.cancel(true);
    }
    this.mBackgroundInitialization = null;

    // Display the home screen
    Intent homeScreenIntent = new Intent(context, ActivityHomeScreen.class);
    try {   
           startActivity(homeScreenIntent);

           // And quit this activity so that when the home screen activity
           // finishes then the application finishes
           this.finish();
    } catch(ActivityNotFoundException e) {
            errorMessage = "Cannot find activity for intent: " + homeScreenIntent.toString();
    } catch(Exception e) {
            errorMessage = "Unknown exception when launching intent: " + homeScreenIntent.toString();
    }
    Log.e("App", errorMessage);
    this.finish();
    }

Выход logcat успешного первого запуска, обратите внимание, что метод doInBackground () объявляет о себе, и инициализация завершается:

01-22 23:59:30.133 10195 10195 D App: AsynchTaskInitializeApplication constructor called
01-22 23:59:30.133 10195 10195 D App: AsynchTaskInitializeApplication::setTheActivity() called
01-22 23:59:30.133 10195 10195 D App: ActivitySplashScreen::onCreate() start the background initialization
01-22 23:59:30.133 10195 10195 D App: AsynchTaskInitializeApplication::onPreExecute() called
01-22 23:59:30.133 10195 10195 D App: ActivitySplashScreen::onCreate() background initialization should have started
01-22 23:59:30.157 10195 10207 D App: AsynchTaskInitializeApplication::doInBackground() called
01-22 23:59:30.477 10195 10195 D App: Initialization is complete true

Выход logcat второго запуска, где doInBackground() не запускается:

01-23 00:02:45.868 10195 10195 D App: AsynchTaskInitializeApplication constructor called
01-23 00:02:45.868 10195 10195 D App: AsynchTaskInitializeApplication::setTheActivity() called
01-23 00:02:45.868 10195 10195 D App: ActivitySplashScreen::onCreate() start the background initialization
01-23 00:02:45.868 10195 10195 D App: AsynchTaskInitializeApplication::onPreExecute() called
01-23 00:02:45.868 10195 10195 D App: ActivitySplashScreen::onCreate() background initialization should have started

Ответы [ 2 ]

0 голосов
/ 23 января 2012

Рекомендую регистрировать статус асинктаск.

0 голосов
/ 23 января 2012

Я думаю, что ваш ответ заключается в использовании не только метода onCreate (). Если вы знакомы с жизненным циклом действия: http://developer.android.com/reference/android/app/Activity.html

Вы знаете, что когда ваше приложение переходит в разные состояния, вы можете вызывать разные методы для обработки нового состояния. В этом случае вы хотите убедиться, что, как и при первом запуске приложения, AsyncTask, вызывающий проблемы, был уничтожен. Использование:

    myAsyncTask.cancel();

Где это уместно для вашего приложения, чтобы попытаться завершить задачу.

http://developer.android.com/reference/android/os/AsyncTask.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...