问题
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