在我的启动画面活动中,我运行了一些冗长的初始化。所以我创建了一个后台异步任务并执行它以完成繁重的工作。然后,主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
答案 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的状态。