有关如何检查活动是否仍然存在的AsyncTask最佳实践

时间:2011-08-03 16:01:08

标签: android android-asynctask

AsyncTask完成后,我通常会执行以下操作之一;

  1. 在我在活动中定义的回调对象/接口上调用方法,并传递给My AsyncTask子类构造函数。
  2. 使用Handler提供AsyncTask,并在任务完成时调用myHandler.sendMessage()。
  3. 我想问的是AsyncTask完成后被认为是最佳实践。如果用户在处理任务时按下了主页按钮,则该活动不再是最重要的。一旦应用程序尝试某些UI操作,作为对任务完成的响应,操作系统就会抛出一个WindowManager $ BadTokenException。

    我当然可以使用BadTokenException的catch包围我的UI代码。这看起来很丑陋。有没有办法判断活动是否在前面?

4 个答案:

答案 0 :(得分:2)

也许你不会喜欢我的回答,但我认为AsyncTask被打破了(出于这样的原因)。

编辑:我的初始答案建议使用IntentService并广播结果。这和给自己寄信一样低效。

您可以使用解决AsyncTask问题的AsyncTaskLoader,但AsyncTaskLoader的API也远非完美。特别是,您必须确保loa​​der id是唯一的,并且要注意结果是为id而不是参数缓存的。此外,异常的传播与AsyncTask一样破坏。

解决问题的一种更现代,更安全的方法是使用Guava future

答案 1 :(得分:1)

这意味着您正在使用某些不适合的上下文。要清除您对异常的疑问,请参阅此链接。 Bad Token Exception

答案 2 :(得分:1)

您可以检查活动是否有效。我通常将我的AsyncTask子类设为静态(以避免内存泄漏),因此我传递了一个活动的引用(包装在WeakReference上,再次避免内存泄漏)。

当onPostExecute正在执行时,我在使用WeakReferences并为活动调用Activity.isFinishing()时进行必要的检查,因此我可以检查活动是否正在被破坏,以避免在垂死的Activity上执行UI更改。

答案 3 :(得分:0)

在onStart()中将活动的对象定义为静态成员 -

private static MyActivity mActivity = null;
public void onStart() {
    mActivity = this;
}

public void onDestroy() {
    mActivity = null;
}

然后在AsyncTask方法上执行以下操作:

if (mActivity != null) {
    mActivity.doSomething();  //make sure to use static member
}