如何在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<MyActivity> 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 类,则将其设为静态。 使用 WeakReference 来引用你的 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 [重复]的主要内容,如果未能解决你的问题,请参考以下文章