AsyncTask不会在下一个Activity调用上运行

时间:2012-01-23 04:25:47

标签: android android-asynctask

在我的启动画面活动中,我运行了一些冗长的初始化。所以我创建了一个后台异步任务并执行它以完成繁重的工作。然后,主Activity(UI)线程显示启动屏幕图像并从onCreate()方法返回,这会导致屏幕更新。当Asynch任务完成时,它会调用启动屏幕活动上的一个方法,该方法调用主活动并终止自身。

第一次运行应用程序时,这非常有用。如果我终止应用程序然后重新启动它,则会创建一个全新的异步任务,并且当调用execute方法时,将调用onPreExecute()方法,但在第二次运行时永远不会调用doInBackground()方法。

如果我使用任务管理器强制终止应用程序,那么它可以正常工作。当应用程序完成(显示设备主屏幕)但尚未被操作系统回收时会出现问题。

我创建了一个全新的Async Task对象,并在调用execute()方法之前检查它是否未被取消。它好像Async Task记得有关前一个实例并且无法启动新的异步任务,因为它认为它已经执行了一次。

为什么全新的Async Task在调用execute时不调用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 :(得分:0)

我认为您的答案在于使用的不仅仅是onCreate()方法。如果您熟悉活动生命周期:http://developer.android.com/reference/android/app/Activity.html

您知道当您的应用进入不同状态时,您可以调用不同的方法来处理新状态。在这种情况下,您希望确保就像第一次运行应用程序时一样,似乎导致问题的AsyncTask已被破坏。使用:

    myAsyncTask.cancel();

适合您的应用尝试结束任务。

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

答案 1 :(得分:0)

我建议记录asynctask的状态。