在对象不再在列表中后停止在对象内启动的线程?

时间:2013-08-09 06:35:41

标签: java android

说我有一个类调用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();
}

2 个答案:

答案 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 } }