0

I know there are tons of questions and answers on this topic here but I am not able to resolve the below issue to resume a thread in my app.

heres is my runnable:-

Runnable ViewPagerVisibleScroll= new Runnable() {
    @Override
    public void run() {
                if (i <= mAdapter.getCount() - 1) {
                    verticalViewPager.setCurrentItem(i, true);
                    handler.postDelayed(ViewPagerVisibleScroll, 3000);

                    i++;
                    while (isPaused) {
                        synchronized (ViewPagerVisibleScroll) {
                            // wait for resume() to be called
                            try {
                                ViewPagerVisibleScroll.wait();
                                //  isPaused = false;
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                        }
                    }
                }
    }
};

pause and resume methods:-

public void pause() {
    synchronized (ViewPagerVisibleScroll) {
        isPaused = true;
    }
}

public synchronized void resume() {
    synchronized (ViewPagerVisibleScroll) {
        isPaused = false;
        // notify anybody waiting on "this"
        ViewPagerVisibleScroll.notify();
    }
}

My problem is that thread will pause() when I call pause method but it will not resume when I call resume(). Please help me to get rid of this issue.

Himanshu Rathore
  • 108
  • 3
  • 11

1 Answers1

0

First of all, I see this code:

public void pause() {
    synchronized (ViewPagerVisibleScroll) {
        isPaused = true;   //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
}

public synchronized void resume() {
    synchronized (ViewPagerVisibleScroll) {
        isPaused = false;
        // notify anybody waiting on "this"
        ViewPagerVisibleScroll.notify();
    }
}

and this:

while (isPaused)

I can guarantee that if you invoke method pause(), i.e. you set isPaused to true, then this loop will be executed while isPaused is true. You should use !isPaused:

while (!isPaused)

i.e. while NOT paused do something. This was just an introduction.

So, back to your problem, I recoment you do next:
1). Create static final objects for synchronization:

private static final Object syncObj = new Object();
private static final Object stopSyncObj = new Object();

2). Implement your runnable as inner class:

public class MyRunnable implements Runnable {

        private boolean isPaused;
        private boolean isStopped;

        public MyRunnable(){
            synchronized (stopSyncObj){
                isStopped = false;
            }
            synchronized (syncObj){
                isPaused = false;
            }
        }

        @Override
        public void run() {
            if (i <= mAdapter.getCount() - 1) {
                verticalViewPager.setCurrentItem(i, true);
                handler.postDelayed(ViewPagerVisibleScroll, 3000);

                i++;

                //Check thread
                boolean isStopped = false;

                while (!isStopped) {
                    synchronized (syncObj) {
                        boolean isPaused = false;
                        synchronized (syncObj){
                            isPaused = this.isPaused;
                        }

                        if(isPaused) {
                            // wait for resume() to be called
                            try {
                                syncObj.wait();
                                //  isPaused = false;
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }else{
                            //do somethinghere

                        }
                    }

                    //Check 'stop' flag
                    synchronized (stopSyncObj){
                        isStopped = this.isStopped;
                    }
                }
            }
        }

        //This method stops runnable forever
        public void stopRunnable(){
            synchronized (stopSyncObj){
                isStopped = true;
            }
        }

        public void pause(){
            synchronized (syncObj){
                isPaused = true;
            }
        }

        public void resume(){
            synchronized (syncObj){
                isPaused = false;
                syncObj.notifyAll();
            }
        }
    }

3). Use it:

Runnable ViewPagerVisibleScroll = new MyRunnable();

UPDATED ANSWER
For autoscrolling use ScheduledThreadPoolExecutor:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
        executor.schedule(new Runnable() {
            @Override
            public void run() {
                //scroll viewpager
            }
        }, 3, TimeUnit.SECONDS);

To stop it use:

executor.shutdown();
Aleksandr
  • 4,906
  • 4
  • 32
  • 47