如何在Android中强制停止AsyncTask [重复]

Posted

技术标签:

【中文标题】如何在Android中强制停止AsyncTask [重复]【英文标题】:How to force stoping AsyncTask in Android [duplicate] 【发布时间】:2014-11-30 17:11:47 【问题描述】:

在我的应用程序中,我有一个 AsyncTask 并且我还创建了一个列表,以将任务添加到该列表中。 在 AsyncTask 我正在下载一些信息,它工作得很好,但是,当使用 finish() 关闭活动时,我经常得到强制关闭,因为 AsyncTask 没有关闭并且当它到达 onPostExecute 并想要与 UI 交互时,它崩溃导致活动已被破坏!

这是我尝试过但没有奏效的方法:

  for (int i = 0; i<tasks.size(); i++)
           tasks.get(i).cancel(true);
       
  finish();

那么有没有办法强制停止 AsyncTasks ?

【问题讨论】:

使用myAsynTask.cancel(true); 他已经这样做了。而且这个问题不是重复的。 【参考方案1】:

您对asyncTask.cancel(true) 感兴趣,实际上在其参数中传递了 true,就像在文档中一样:

mayInterruptIfRunning 如果执行此任务的线程应该被中断,则为 true;否则,允许完成正在进行的任务。

然后在您的 AsyncTask.doInBackground 中,您可以进行如下尝试/捕获 - 但这需要您进行引发 InterruptedException 的阻塞调用,否则您需要不时检查 isCancelled():

@Override
protected Void doInBackground(Void... params) 
  try 
    /// do work, 
   catch (InterruptedException e) 
    if ( isCancelled() ) 
      // cancel(true) called, dont touch UI!
    
  
  return null;

另外,在onPostExecute() 的开头检查 isCancelled() 是安全的。

当它到达 onPostExecute 并想要与 UI 交互时,它会崩溃

这是另一个问题,如果您在AsyncTask 内部与 GUI 进行交互,我建议首先:使您的 AsyncTask 成为静态类,将对您的 Activity 或 Fragment 的引用传递给 AsyncTask 构造函数,然后将其存储为WeakReference&lt;MyActivity&gt; actRef。然后当你需要它时使用 if ( actRef.get() != null ) // 使用它。 。这样,您希望泄漏对您的活动/片段的引用或使用无效的 UI 对象。

【讨论】:

【参考方案2】:

尝试创建自己的布尔变量。

boolean stopNow = false;
asyncTask.start();

...异步内部:

while( ...)
 
   if( stopNow == true)  finish(); // return();
   ... your main async code
 

.... 在异步之外(当您需要强制停止异步时,在您的情况下是 Activity.onDestroy() 或 Activity.onPause()):

stopNow = true; 

【讨论】:

【参考方案3】:

您需要告诉您的AsyncTask,它将取消其工作。因此,您需要在您的AsyncTask 实现中定期检查self.isCanceled()。如果结果为true,则您的实现需要停止其工作,否则它将完成整个工作或永远运行,具体取决于实现。

【讨论】:

【参考方案4】:

您应该检查 AsyncTask 的 onPostExecute 中的活动是否为 isDestroyed()。 此外,如果您使用的是内部 AsyncTask 类,则将其设为静态。 使用 Wea​​kReference 来引用你的 Activity 以防止内存泄漏。 (没有办法强制停止 AsyncTask)。

【讨论】:

怎么样onCancelled()方法stated in official doc in Cancelling a task section 此方法不会中断您的任务。它在您的任务完成后被调用。【参考方案5】:

这里是如何实现这个的例子......

public class MyTask extends AsyncTask<Void, Void, Void> 

private volatile boolean running = true;
private final ProgressDialog progressDialog;

public MyTask(Context ctx) 
    progressDialog = gimmeOne(ctx);

    progressDialog.setCancelable(true);
    progressDialog.setOnCancelListener(new OnCancelListener() 
        @Override
        public void onCancel(DialogInterface dialog) 
            // actually could set running = false; right here, but I'll
            // stick to contract.
            cancel(true);
        
    );



@Override
protected void onPreExecute() 
    progressDialog.show();


@Override
protected void onCancelled() 
    running = false;


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

    while (running) 
        // does the hard work
    
    return null;


// ...


【讨论】:

以上是关于如何在Android中强制停止AsyncTask [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中停止异步任务线程?

Android:AsyncTask Object[] 不能在 doInBackground 中强制转换

如何以编程方式强制停止我的 android 应用程序?

Android开发--取消AsyncTask

如何在切换片段时停止 AsyncTask?

即使 Activity 已销毁,AsyncTask 也不会停止