Android AsyncTask在取消时不会停止,为什么?

时间:2011-02-10 16:14:02

标签: android android-asynctask

我有一个AsyncTask,我在Activity的onPause生命周期事件中关闭,因此当有人离开应用程序时它不会运行,但它会继续运行,尽管如此。我添加了一些跟踪,这个片段显示了问题。

    Trace.d(TAG,"Task state: " + myTask.getStatus() );
    myTask.cancel(true);
    Trace.d(TAG,"Task state: " + myTask.getStatus() );

输出:

Task state: RUNNING
Task state: RUNNING

为什么cancel()方法对任务的状态没有任何影响?我注意到文档说取消方法将“尝试”停止任务,但在什么情况下会失败?该任务肯定在运行,因为它每十秒输出一次日志输出,正如您在上面所看到的,它的状态将返回为运行状态。

更新:我添加了跟踪以显示isCancelled()状态,并且会更改。所以取消(true)的调用是将取消状态从false更改为true,但显然对Status没有影响,或者停止线程。

5 个答案:

答案 0 :(得分:3)

请记住,您的Activity和AsyncTask是两个独立的线程。因此,即使取消AsyncTask,取消任务的代码也可能无法运行!这就是为什么即使在修复bug之后你仍然看到AsyncTask仍在运行的原因。在AsyncTask完成doInBackground()之前,我认为状态不会改变。 (因此,请确保您正在检查isCancelled()并在取消时提前返回!)

答案 1 :(得分:2)

我深入挖掘并记得我的线程正在调用一个写得很糟糕的方法,在我需要取消的那个内部生成另一个线程:

public static void haveASleep(int milliseconds)
{
    try
    {
        Thread.sleep(milliseconds);
    }
    catch (InterruptedException ie)
    {
        Trace.w(TAG,"Sleep interrupted");
    }
}

所以发生的事情是AsyncTask线程调用此方法等待一段时间,并且在睡眠期间,在AsyncTask上发生cancel()方法调用,这会导致线程休眠中出现异常。我的代码无益地捕获并吸收了该异常,而不是使用它来关闭AsyncTask。

解决方案是在睡眠中寻找异常,如果抛出异常,则静静地退出线程。该应用现在按预期工作,但是......

cancel()方法调用之后的状态仍然是RUNNING,但我怀疑这是因为此时它仍在运行,并且操作系统尚未将其关闭。我不知道这是否属实,但那是我最好的估计。

答案 2 :(得分:2)

thread.cancel(true);

仅在AsyncTask类中设置变量。你需要做的是在你的后台任务中实现一个循环,如果你还没有。如果每次迭代取消为真,则检查并中断循环。

@Override  
protected Void doInBackground(Void... params) {  

    synchronized(this) {

        for(int i = 0; i < 9000; i++) {

            if(thread.isCancelled()) break;

            // do stuff

        }

    }

}

然后只需在需要停止时将其设置为取消。然后它将在下一次迭代之前停止。

@Override
public void onStop() {

    super.onStop();

    thread.cancel(true);

}

@Override
public void onDestroy() {

    super.onDestroy();

    thread.cancel(true);

}

答案 3 :(得分:0)

即使您知道取消是如何工作的,也很难确定您的线程将在什么状态下停止。所以我建议你实现自己的安全方法来阻止你的线程,这样你就可以确定你停止了什么状态,你确定没有内存泄漏等等。从更多信息如何在java中停止一个线程安全检查此帖子How to abort a thread in a fast and clean way in java?

答案 4 :(得分:0)

检查您是否遇到此问题的另一个可能的陷阱:

确保您没有启动两个AsyncTasks。