У меня есть несколько загрузок, которые отправляются в качестве задач на ThreadPoolExecutor
. Теперь я создаю этот ThreadPoolExecutor
в глобальном классе, который расширяет Application
. Я храню все отправленные задачи в хэш-карте с идентификаторами.
У меня есть представление списка во фрагменте. Этот элемент представления списка содержит кнопки паузы и возобновления. Когда я нажимаю на сам элемент списка, загрузка FutureTask
отправляется исполнителю глобального пула. Теперь, когда я нажимаю кнопку паузы элемента списка, я хочу, чтобы эта конкретная задача была приостановлена.
У меня есть метод onClick
кнопки паузы в пользовательском адаптере моего представления списка. Итак, когда я нажимаю кнопку, в моем классе адаптера я получаю будущую задачу, связанную с этим элементом списка, по имени, а затем делаю .cancel()
. Когда я проверяю значение isCancelled()
, оно возвращает true
. Это означает, что задача была отменена, но моя загрузка все еще продолжается, и файл загружается полностью. Как я могу это решить? Любая помощь будет оценена по достоинству.
PS: я также пытался отправлять потоки с runnable, переданным в качестве аргумента исполнителю. Затем я бы получил поток по его имени (используя пользовательский ThreadFactory
, который возвращает поток с именем), а затем вызывал thread.wait()
до тех пор, пока кнопка возобновления не будет нажата снова. Тоже не работает!
Вот пример кода:
Мой класс GlobalState:
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());
}
}
}
Мой метод загрузки, который написан внутри моего класса фрагментов. выполняется при щелчке элемента списка:
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);
}
Код адаптера моего пользовательского списка внутри кнопки паузы при нажатии кнопки:
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
needToPause = true;
globalstate.pauseTaskMain(threadname);
}
}
На самом деле я предпочитаю приостанавливать и возобновлять свою задачу, используя функцию ожидания () или что-то в этом роде, а не полностью отменять задачу. Любая помощь будет оценена по достоинству. Благодарю вас!
cancelTaskMain
кажется правильным, но отмена — это кооперативная вещь, поэтому ваша задача также должна прослушивать отмену и делать что-то, чтобы она работала.pauseTaskMain
совершенно неверно. Вы не можете просто приостановить задачу — все, что вам нужно сделать, это приостановить поток, который вызываетpauseTaskMain
. - person isnot2bad   schedule 16.03.2015