简体   繁体   中英

wait() method on thread not working Android

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 ListView in a Fragment . This ListView 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 thread to pause/wait.

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 all the threads that are currently running, put them in an array and then get the thread with the name I want from the array. I can see in my log that the thread I want to get is running with the name I set. So once I get that thread, I do wait() on it.

In the onclick of my resume button, I notify that particular thread and set the flag to pause as false so that the thread resumes. But, the download inside that thread actually keeps running even after clicking pause. I do not know where I am going wrong.

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, Thread task){
        Future<?> longRunningTaskFuture = mainExec.submit(task);
        futureMapMain.put(name, longRunningTaskFuture);
    }

    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(){

Thread dThread = new Thread(new Runnable() {

                final Handler pdfHandler = new Handler();

                @Override
                public void run() {
                    for(something){
/* DOES SOME DOWNLOAD USING url.getcontent() with different urls in a loop and stores files to sd card. */
}
}
}
dThread.setName(threadname);
            Log.d("Tel Frag", "Thread name set as: "+dThread.getName());
            mainGs.settName(threadname);
            mainGs.submitTaskMain(threadname, dThread);
}

onclick of my pause button inside custom list adapter:

    pause.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

                needToPause = true;

                Runnable runnable = new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub

                        Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
                        Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
                        Log.d("CLA", "Threads running size: "+threadArray.length); 

                        Thread neededThread = null;

                         for ( Thread thread : threadArray ){
                             Log.d("CustomListAdapter", "Thread name in array: "+thread.getName());
                                if (thread.getName( ).equals(threadname)){
                                    neededThread = thread;
                                }
                         }   

                         if(neededThread!=null){
                            while(needToPause){
                                synchronized  (neededThread) {
                                        try {
                                            neededThread.wait();
                                        } catch (InterruptedException e) {
                                            // TODO Auto-generated catch block
                                            e.printStackTrace();
                                        }
                                }
                            }
                         } 
                    }
                };
                new Thread(runnable).start();

                notifyDataSetChanged();
        }
    });

onclick of my resume button written inside custom list adapter class:

resume.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            needToPause = false;

            Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
            Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);

             for ( Thread thread : threadArray ){
                    if ( thread.getName( ).equals(threadname) ){
                        thread.notify();
                    }
             }  


            notifyDataSetChanged();
        }
    });

I have been trying to figure it out for 2 days now but no luck. I went through a lot of examples and stackoverflow questions. I am just trying to get a thread by its name and then pause and resume it. Any help would be appreciated. Thank you!

You can't reliably use wait() and notify() on Thread objects. This is clearly stated in the Javadoc. You already have Future objects, you shouldn't be using other mechanisms anyway.

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