【问题标题】:Android, pausing and resuming handler callbacksAndroid,暂停和恢复处理程序回调
【发布时间】:2011-05-24 15:39:54
【问题描述】:

我有一个处理程序,我正在使用如下:

handler.postDelayed(Play, 1000);

在完成之前调用我的应用程序 onPause() 时,我需要暂停它并告诉它在我恢复之前不要执行“postDelayed”。

这可能吗,或者有其他方法吗?

我的问题是,当调用 onPause() 时,我会暂停音频(SoundManager),但如果在此之后调用此 handler.postDelayed,音频将不会暂停,并将继续在后台与我的应用程序一起播放。

@Override
public void onPause()
{
  Soundmanager.autoPause()
}

但是 postDelayed 1000ms 后又开始播放音频了。

【问题讨论】:

    标签: android callback handler


    【解决方案1】:

    您需要继承Handler 并实现以下暂停/恢复方法(然后,当您想暂停消息处理时只需调用handler.pause(),当您想重新启动它时调用handler.resume()):

    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
                   // ...
            }
        }
        //...
    }
    

    【讨论】:

    • 没有运行方法。处理程序不是一个单独的线程(它在您的线程中运行)。
    • 对于查看此页面的任何人,请使用此而不是接受的答案。真棒
    • 一个很好的解决方案。应该是公认的答案。到目前为止,这是实现此功能的最佳方式。
    • @CpnCrunch 对post(runnable) 也有效吗?
    • 好的,所以不是取消 onPause 中的线程,而是仅在恢复之前的时间用完时才重新启动处理程序。
    【解决方案2】:

    您是否尝试过:

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

    德国

    【讨论】:

    • 是的,但是如果我恢复这个,回调被删除的声音永远不会开始播放,所以没有什么可以恢复的。我仍然希望它恢复那个声音。 (如果尚未启动,则启动它)。
    • 你可以实现 onResume 方法并在那里执行 handler.postDelayed(Play, 1000);
    • 这是很久以前的事了,自从这个问题以来,我有了重要的 Android 经验。我会接受这个答案,因为我应该在暂停时删除回调是正确的。
    【解决方案3】:

    修改CpcCrunch给出的答案。 handleMessage 对我不起作用,所以使用 dispatchMessage 代替它。注意:以下代码是用 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)
            }
        }
    }
    

    【讨论】:

    • 经过数小时的挫折后,这为我解决了这个问题。我不知道为什么我一开始没有稍微向下滚动看到这个。
    【解决方案4】:
    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);
    
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      当我想在队列中暂停/恢复 Runnables 时,我想出了一个替代 CpnCrunch 的方法。要在仍然连接且处于离线状态时调用已调用的方法,一旦在线,恢复队列并执行所有可运行对象。

      不要使用Handler,而是使用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);
              }
          }
      }
      

      使用方法与Handler类似,但不是post(runnable),而是使用execute(runnable)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-06
        • 1970-01-01
        相关资源
        最近更新 更多