Android, pausing and resuming handler callbacks

前端 未结 5 1139
遥遥无期
遥遥无期 2020-12-03 11:50

I have a handler that I am using as follows:

handler.postDelayed(Play, 1000);

when my application onPause() is called before this is done,

相关标签:
5条回答
  • 2020-12-03 11:54

    You need to subclass Handler and implement pause/resume methods as follows (then just call handler.pause() when you want to pause message handling, and call handler.resume() when you want to restart it):

    class MyHandler extends Handler {
        Stack<Message> s = new Stack<Message>();
        boolean is_paused = false;
    
        public synchronized void pause() {
            is_paused = true;
        }
    
        public synchronized void resume() {
            is_paused = false;
            while (!s.empty()) {
                sendMessageAtFrontOfQueue(s.pop());
            }
        }
    
        @Override
        public void handleMessage(Message msg) {
            if (is_paused) {
                s.push(Message.obtain(msg));
                return;
            }else{
                   super.handleMessage(msg);
                   // otherwise handle message as normal
                   // ...
            }
        }
        //...
    }
    
    0 讨论(0)
  • 2020-12-03 11:57

    Modifying the answer given by CpcCrunch. There handleMessage not worked for me, so instead of it using dispatchMessage. Note: Below code is written in Kotlin:

    class CustomHandler: Handler() {
    
        var s = Stack<Message>()
        var is_paused = false
    
        @Synchronized
        fun pause() {
            is_paused = true
        }
    
        @Synchronized
        fun resume() {
            is_paused = false
            while (!s.empty()) {
                sendMessageAtFrontOfQueue(s.pop())
            }
        }
    
        override fun dispatchMessage(msg: Message?) {
            if (is_paused) {
                s.push(Message.obtain(msg))
                return
            } else {
                super.dispatchMessage(msg)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-03 11:59
    public class YourActivity extends AppCompatActivity {
    
        private static boolean handlerflag=false;
        private Handler handler;
        private Runnable runnable;
        private int myind=0,index=0,count=0;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.your_activtiy);         
            //oncreate exe only
            handlerflag=true;
            handler = new Handler();
            startyourtime(0);
     }
      private void  startyourtime(int a) {
    
        myind=0;
        for (index=a; index<10 ;index++) {
                myind++;
                runnable=new Runnable() {
                    count++;
                    @Override
                    public void run() {
                              //your code here
                   }
                };handler.postDelayed(runnable, Constants.TIME_LIMIT * myind);
    
       }
        @Override
        protected void onPause() {
            super.onPause();
            handlerflag=false;
            handler.removeCallbacksAndMessages(null);
        }
        @Override
        protected void onResume() {
            super.onResume();
            if(!handlerflag)
            {
               startyourtime(count);
    
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-03 12:05

    I came up with an alternative to CpnCrunch when wanting to pause/resume Runnables in a queue. To have methods that has been called whilst still connecting and is offline, once online, resume the queue and all runnables are executed.

    Instead of using Handler, use ExecutorService:

    public class ExecutorQueueService extends ThreadPoolExecutor {
        private Stack<Runnable> runnables = new Stack<>();
        private boolean paused = false;
    
        public ExecutorQueueService() {
            super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
        }
    
        public synchronized void pause() {
            paused = true;
        }
    
        public synchronized void resume() {
            paused = false;
            while (!runnables.empty()) {
                execute(runnables.pop());
            }
        }
    
        public synchronized boolean isPaused() {
            return paused;
        }
    
        @Override
        public void execute(Runnable runnable) {
            if (paused) {
                runnables.push(runnable);
            } else {
                super.execute(runnable);
            }
        }
    }
    

    Using it is similar to Handler, but instead of post(runnable), use execute(runnable)

    0 讨论(0)
  • 2020-12-03 12:07

    Have you tried with:

    @Override
    public void onPause()
    {
      handler.removeCallbacks(Play);
      Soundmanager.autoPause()
    }
    

    Ger

    0 讨论(0)
提交回复
热议问题