简体   繁体   中英

Strange behaviour of extended AsyncTask class

I'm using my own generic abstract class (MyAsyncTask) which extends AsyncTasks, and need a way to cancel all currently running MyAsyncTasks.

abstract class MyAsyncTask<Params, Progress, Result> 
         extends AsyncTask<Params, Progress, Result> {
    ...
}

So I decided to store references to all tasks in WeakHashMap. Since MyAsincTask is a generic class, I can't plainly use it as HasMaps key type. As the only thing I have to know about objects stored in this HashMap is that they have method

public Boolean cancel(Boolean mayInterruptIfRunning);

it seemed reasonable to me to write an interface

interface Cancelable {
    public Boolean cancel(Boolean mayInterruptIfRunning);
}

and make MyAsyncTask implement it:

abstract class MyAsyncTask<Params, Progress, Result> 
         extends AsyncTask<Params, Progress, Result> implements Cancelable {

    private static WeakHashMap<Cancelable, Void> taskList = new WeakHashMap<Cancelable, Void>();

    public MyAsyncTask() {
        taskList.add(this, null);
    }

    public static void cancelAll() {
            Iterator<Cancelable> iterator = taskList.keySet().iterator();

            while (iterator.hasNext()) {
                Cancelable task = iterator.next();

                if (task != null) {
                    task.cancel(true);
                    iterator.remove();
                }
            }
    }

    ...

}

The confusing part is that even though AsyncTask has a final method cancel, which is defined exactly as in my interface, I still have to implement it in my class.

    public Boolean cancel(Boolean mayInterruptIfRunning) {
            return super.cancel(mayInterruptIfRunning);
    }

Now my questions are: 1) Why am I allowed to define this cancel method, even though there is the same final method in the superclass? 2) Which one - the original one or my method would be executed if I do something like new MyAsyncTask().cancel(); ?

I've tried to simulate this situation in plain java

abstract interface A {
    public Boolean cancel(Boolean a);
}

abstract class B<T> {
    public final Boolean cancel(Boolean a) {
        System.out.println("B.cacncel called");
        return a;
    }
}

abstract class C<T> extends B<T> implements A {}

class D extends C<Void> {}

class TestApp {
    public static void main(String[] args) {
        D x = new D();
        x.cancel(true);
    }
}

But in this case I don't have to implement cancel method in class D, as it was already implemented in class B. So, what's so special about AsyncTask and why do I have to reimplement cancel method?

Thank you.

No, AsyncTask has boolean cancel(boolean) while you have Boolean cancel(Boolean)

This class compiles fine

public class Test {

    public Boolean d(Boolean v) { return false; }

    public boolean d1(boolean v1) { return true; } 

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM