0

Say I have a class call MyTask

Every time I new a object for MyTask, it will create a thread

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

At first I new myTask1, myTask2, myTask3 then add to the List

List<MyTask> myTasks = new ArrayList<MyTask>;
myTasks.add(myTask1);
myTasks.add(myTask2);
myTasks.add(myTask3);

Now there should be 3 threads run on the background, then I renew the by

myTasks = new ArrayList<MyTask>;

And looks like those threads in myTask1, myTask2, myTask3 are still running, the finalize never get called. I know I can set mContinueThread as true for each MyTask objects before I renew the list, but I would like to know is there any way (callback?) I can know those MyTask objects are not no longer in the list and then set mContinueThread as false?

public MyTask (Activity activity) {

    ...

  @Override
protected void finalize() throws Throwable {
    mContinueThread = false;
    super.finalize();
}
Arst
  • 3,098
  • 1
  • 35
  • 42

2 Answers2

1

It seems redundant to have an async task which just starts a Thread.You can achieve the desired outcome, by puting the contance of the thread directly into you AsyncTask$doInBackground()

You can call the call the AsyncTask$cancel(boolean mayInterrupt) method, this will rise an InterruptedException, the only thing left to do, is adding a return statement within the catch:

    @Override
    protected Void doInBackground(Void... params) {
        try {
             Thread.sleep(1000);
        } catch (InterruptedException e) {
             // cancel was called
             return null;
        }
        return null;
    };

Cancel the task like that:

myTasks.get(i).cancel(true);

Don't forget to pass true or it won't work

Kirill Kulakov
  • 10,035
  • 9
  • 50
  • 67
0

you have to have a variable for your AsyncTask first, so that you can call:

myTasks.get(0).getMyAsyncTask().cancel(boolean);

As you can see here, it is not that easy to cancel an AsyncTask. After you call cancel(boolean), it will: (from docs:

invoking this method will cause subsequent call to isCancelled() to return true. onCancelled(Object) will be invoked after doInBackground instead of onPostxecute. To ensure that a task is cancelled, you should always check the return value of isCancelled from doInBackground.

So, you call cancel(booelan) onto your reference variable of your AsyncTask and in doInBackground, you always check for isCancelled() in order to stop some processes in your doInBackground method.

You should handle your doInBackground method manually in order to stop all the executions there. So if you have while(true){ do_something }, then it should become while(true){ if(!isCancelled()) { do_something } }

Community
  • 1
  • 1
Boris Mocialov
  • 3,439
  • 2
  • 28
  • 55