如何停止一系列的postDelayed处理程序

4

我有一系列的postDelayed处理程序。当用户随时点击停止按钮时,我遇到了在设置停止处理程序的方法方面的困难。

如果有人能提供帮助, 我会非常感激。 谢谢。

while (!lessonIsRunning) {
        Handler handler0 = new Handler();
        handler0.postDelayed(new Runnable() {
          @Override
          public void run() {
              plate1.setVisibility(ImageView.VISIBLE);
              plate2.setVisibility(ImageView.VISIBLE);
              plate3.setVisibility(ImageView.VISIBLE);
          }
        }, 6000);

        Handler handler1 = new Handler();
        handler1.postDelayed(new Runnable() {
          @Override
          public void run() {
              apples1.setVisibility(ImageView.VISIBLE);
          }
        }, 9000);

        Handler handler2 = new Handler();
        handler2.postDelayed(new Runnable() {
          @Override
          public void run() {
              plus1.setVisibility(TextView.VISIBLE);
          }
        }, 9250);
}
public void stopLesson(View V){

}

2
为什么你在使用多个处理程序?为什么不使用单个处理程序? - CommonsWare
2个回答

12

不要以匿名方式编写Runnable任务,而是必须为其定义一个名称,以便以后您将拥有一个链接以删除它:

//there is no need for multiple handlers 
//handler must be declared outside all functions, in order for you to use it everywhere. 

Handler handler = new Handler(); 
Runnable myFirstTask  = new Runnable (){
         @Override
              public void run() {
                  plate1.setVisibility(ImageView.VISIBLE);
                  plate2.setVisibility(ImageView.VISIBLE);
                  plate3.setVisibility(ImageView.VISIBLE);
              } };

    Runnable mySecondTask = new Runnable(){
        @Override
              public void run() {
                  plus1.setVisibility(TextView.VISIBLE);
              }

    };

    Runnable myThirdTask = new Runnable(){
        @Override
              public void run() {
                  apples1.setVisibility(ImageView.VISIBLE);
              } }

    //you can put different tasks on the same handler object

    while (!lessonIsRunning) {   
            handler.postDelayed(myFirstTask,6000);   
            handler.postDelayed(mySecondTask,9250);   
            handler.postDelayed(myThirdTask,9000); 
} 
public void stopLesson(View V){ 
    //notice that you don't need these, because the handlers are not recursive 
    //you don't have lines "handler.postDelayed(sameTask,someTime);" 
    //in your run Method of the runnable
 if(handler!=null){
    handler.removeCallbacks(myFirstTask);
    handler.removeCallbacks(mySecondTask); 
    handler.removeCallbacks(myThirdTask); 
    //if this method is inside onPause or onDestroy add this line as well: 
    handler=null; 

}
 }

你尝试过使用 removeCallbacksAndMessages(null) 这个方法吗?它可以代替三行代码中的 removeCallback(runnable)。我不介意你是否这样做,只是想知道它是否有效,因为文档上是这么说的。 - Bruno Mateus
可能还有其他回调函数,您不希望被删除。 - Lena Bru
我知道,但在这种特定情况下呢?可行吗?因为@RBZ遇到了问题。 - Bruno Mateus

4

你可以给

handler0.removeCallbacksAndMessages(null);
handler1.removeCallbacksAndMessages(null);
handler2.removeCallbacksAndMessages(null);

尝试一下。文档中说明,当您提交空令牌时,所有回调和消息都将被删除。


谢谢您的快速回答!问题是当我在handler0播放时停止它,我会在handler1.removeCallbacksAndMessages(null)上得到nullPointerException。有没有一种检查处理程序状态的方法?或者您能想到的任何布尔条件? - RBZ
问题与removeCallbacksAndMessages参数无关。可能是handler1为空。 - Blackbelt
1
@RBZ:此外,只能从处理程序的主线程(例如,主应用程序线程)调用这些方法。 - CommonsWare
1
+1,我还没有尝试过这个,但我总是更喜欢传递对象而不是null。 - Inder Kumar Rathore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接