2014-10-06 139 views
1

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

这是我做过尝试,但没有奏效:

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

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

+2

使用'myAsynTask.cancel(真);' – KOTIOS 2014-10-06 12:35:00

+1

他已经这样做了。这个问题不是重复的。 – konmik 2014-10-07 07:41:05

回答

1

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

2

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

boolean stopNow = false; 
asyncTask.start(); 

...里面异步:

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

....外异步(在那一刻,当你需要强制停止异步,你的情况在Activity.onDestroy()或Activity.onPause( )):

stopNow = true; 
1

您应该检查AsyncTask的onPostExecute中是否有活动isDestroyed()。 此外,如果您使用内部AsyncTask类,然后使其静态。 使用WeakReference引用yout Activity来防止内存泄漏。 (没有办法强制停止AsyncTask)。

+0

'onCancelled()'方法[在取消任务部分的官方文档中声明](http://developer.android.com/reference/android/os/AsyncTask.html#cancel(布尔值)) – kId 2014-10-06 12:58:52

+0

此方法的作用不会中断你的任务。它被称为在你的任务完成后。 – konmik 2014-10-07 07:37:21

3

您intereset在asyncTask.cancel(true),在其实际参数传递true,如文档住宿:

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

那么你AsyncTask.doInBackground里面你可以try/catch语句如下 - 但是这需要你有阻断抛出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对象。

1

这里的例子,如何实现这一目标?

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; 
} 

// ... 

} 
相关问题