说我有一个类调用MyTask
每次我为MyTask创建一个对象时,它都会创建一个线程
boolean mContinueThread = true;
public MyTask (Activity activity) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (mContinueThread) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
});
thread.start();
return null;
};
}.execute();
}
首先我将新的myTask1,myTask2,myTask3添加到List
List<MyTask> myTasks = new ArrayList<MyTask>;
myTasks.add(myTask1);
myTasks.add(myTask2);
myTasks.add(myTask3);
现在应该有3个线程在后台运行,然后我更新了
myTasks = new ArrayList<MyTask>;
看起来myTask1,myTask2,myTask3中的那些线程仍在运行,finalize永远不会被调用。我知道我可以在更新列表之前为每个MyTask对象设置mContinueThread为true,但我想知道有没有办法(回调?)我可以知道那些MyTask对象不再在列表中,然后将mContinueThread设置为假?
public MyTask (Activity activity) {
...
@Override
protected void finalize() throws Throwable {
mContinueThread = false;
super.finalize();
}
答案 0 :(得分:1)
拥有一个只启动Thread
的异步任务似乎是多余的。你可以通过将线程的轮廓直接放入你AsyncTask$doInBackground()
你可以调用AsyncTask$cancel(boolean mayInterrupt)
方法调用,这将会增加InterruptedException
,唯一要做的就是在catch中添加一个return语句:
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// cancel was called
return null;
}
return null;
};
取消这样的任务:
myTasks.get(i).cancel(true);
别忘了通过true
或者它不会工作
答案 1 :(得分:0)
首先必须为AsyncTask创建一个变量,以便调用:
myTasks.get(0).getMyAsyncTask().cancel(boolean);
正如您所见here,取消AsyncTask
并不容易。致电cancel(boolean)
后,它将:(来自docs:
调用此方法将导致后续调用isCancelled() 返回true。在doInBackground之后将调用onCancelled(Object) 而不是onPostxecute。为了确保取消任务,您 应始终检查isCancelled的返回值 doInBackground。
因此,您将cancel(booelan)
调用到AsyncTask
的引用变量上,并且在doInBackground中,您始终检查isCancelled()以停止doInBackground方法中的某些进程。
您应该手动处理doInBackground方法,以便停止那里的所有执行。因此,如果您有while(true){ do_something }
,那么它应该变为while(true){ if(!isCancelled()) { do_something } }