cancel() not working while trying to cancel tasks in ThreadPoolExecutor Android

时光毁灭记忆、已成空白 提交于 2019-12-13 01:24:21

问题


I have a few downloads that are submitted as tasks to a ThreadPoolExecutor. Now, I am creating this ThreadPoolExecutor in a global class that extends Application. I am storing all the submitted tasks in a hashmap with ids.

I have a list view in a fragment. This list view item contains pause and resume buttons. When I click on the list item itself, the download FutureTask is submitted to the global pool executor. Now, when I click on the pause button of the listview item, I want that particular task to pause.

I have the onClick method of the pause button in my list view's custom adapter. So, when I click the button, in my adapter class, I get the future task related to that list item by name and then do .cancel(). When I check for isCancelled() value, it returns true. This means that the task has been cancelled but my download still runs and the file gets completely downloaded. How can I solve this? Any help would be appreciated.

PS: I have also tried submitting threads with runnable passed as argument to the executor. Then, I would get the thread by its name (used a custom ThreadFactory that returns thread with name) and then call thread.wait() until the resume button is pressed again. Does not work either!

Here is the sample code:

My GlobalState Class:

    public class GlobalState extends Application{

        HashMap<String, Future<?>> futureMapMain = new HashMap<String, Future<?>>();

        ThreadPoolExecutor mainExec = new ThreadPoolExecutor(2, 2, 2000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new YourThreadFactory());

        public void submitTaskMain(String name, FutureTask<String> task){
            Future<?> longRunningTaskFuture = mainExec.submit(task);
            futureMapMain.put(name, longRunningTaskFuture);
        }

        public void cancelTaskMain(String name){
            futureMapMain.get(name).cancel(true);
            Log.e("Global State", "task cancelled?: " + futureMapMain.get(name).isCancelled());
            futureMapMain.remove(name);
        }

public void pauseTaskMain(String name){
        paused = true;
        while(paused==true){
        try {
            synchronized(futureMapMain.get(name)){
                futureMapMain.get(name).wait();
            }
        //  Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }

    public void resumeTaskMain(String name){
        paused = false;
        synchronized(futureMapMain.get(name)){
            futureMapMain.get(name).notify();
        }
    }

        public HashMap<String, Future<?>> getFutureMap(){
            return futureMapMain;
        }

        public ThreadPoolExecutor getMainExeutor(){
            return mainExec;
        }

        public class YourThreadFactory implements ThreadFactory {
            public Thread newThread(Runnable r) {
                return new Thread(r, gettName());
            }
        }
    }

My Download Method that is written inside my fragment class. gets executed on list item click:

public void abDownloadTask(){
    FutureTask<String> fTask = new FutureTask<String>(new Callable<String>() {

        @Override
        public String call() throws Exception {
            // TODO Auto-generated method stub
            for(something) {
                /* DOES SOME DOWNLOAD USING url.getcontent() with different urls in a loop and stores files to sd card. */
            }
        }
    }

    mainGs = (GlobalState) getActivity().getApplication();
    mainExec = mainGs.getMainExeutor();
    mainGs.settName(somenameforThread);
    mainGs.submitTaskMain(someNameforThread, fTask);    
}

My custom list Adapter code inside onclick of pause button:

    Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub

                                    needToPause = true;
globalstate.pauseTaskMain(threadname);
            }
        }

I actually prefer pausing and resuming my task using wait() or something like that rather than canceling the task completely. Any help would be appreciated. Thank you!

来源:https://stackoverflow.com/questions/29045575/cancel-not-working-while-trying-to-cancel-tasks-in-threadpoolexecutor-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!