如何停止Handler Runnable?

42

我在以下程序中使用了一个处理器,并且当i=5时希望它停止,但处理器没有停止并继续运行。

   b1.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            handler = new Handler();
           runnable = new Runnable() {
                 public void run() {

                    try {
                        Toast.makeText(getApplicationContext(), "Handler is working", Toast.LENGTH_LONG).show();
                        System.out.print("Handler is working");

                       if(i==5){
                           //Thread.currentThread().interrupt();
                            handler.removeCallbacks(runnable);


                            System.out.print("ok");
                                        Toast.makeText(getApplicationContext(), "ok", Toast.LENGTH_LONG).show();
                        }
                       i++;
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 
                   handler.postDelayed(this, 5000); 

               }
           };
           handler.postDelayed(runnable, 5000);
           //return;
        }
    });

你已经有了这个 handler.removeCallbacks(runnable);,请参考 http://developer.android.com/reference/android/os/Handler.html。 - Raghunandan
你也可以使用倒计时器、处理程序或定时器任务。 - Raghunandan
可能是cancelling a handler.postdelayed process的重复问题。 - Varun
停止可运行的线程。https://dev59.com/smox5IYBdhLWcg3wDgTR#58038337 - Shomu
4个回答

60

由于您在删除回调后再次调用了postDelayed()。请使用以下代码:

final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
         public void run() {
               Log.d("Runnable","Handler is working");
               if(i == 5){ // just remove call backs
                    handler.removeCallbacks(this); 
                    Log.d("Runnable","ok");
                } else { // post again
                    i++;
                    handler.postDelayed(this, 5000); 
                }
       }
   };

//now somewhere in a method
 b1.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        handler.removeCallbacks(runnable); 
        handler.postDelayed(runnable, 5000); 
    }
});

你能否解释一下为什么你写了两次handler.postDelayed(runnable, 5000)? - Ajit Kumar Dubey
@AjitDubey,也许最新的编辑会帮助您更好地理解。 - M-Wajeeh
@M-WaJeEh- 我的理解是,第一个 postDelayed(runnable, 5000) 将在 5 秒后启动,而另一个(在 run 方法内部的)将开始计算 5 秒的间隔。我是对的吗? - Ajit Kumar Dubey
是的,首先postDelayed是用来启动runnable的,它会一直运行直到i==5为真。 - M-Wajeeh
请帮忙解决这个问题:http://stackoverflow.com/questions/40954945/how-to-pause-resume-or-stop-a-thread-and-display-a-popup - Si8

27
protected void onStop() {
    super.onStop();
    handler.removeCallbacks(runnable);
}

你可以像这样停止它


停止可运行的线程。https://dev59.com/smox5IYBdhLWcg3wDgTR#58038337 - Shomu

1
刚看到这个问题。 我会使用CountDownTimer()。 总共运行5秒,每秒一次:
new CountDownTimer(5000, 1000) {
    public void onTick(long milsecRemain) {
        // Code to run every second
        Log.i("Seconds left", String.valueOf(milsecRemain/1000));
}
    public void onFinish() {
        // 10 seconds have passed
    }
}.start();

0

我找到了一个适合我的解决方案。这是一个代码示例,我期望计时器停止,但我发现它仍然在运行,即使我已经退出了活动:

boolean bFlagForceExit = false; 
Handler timerHandler = new Handler();
private   Runnable timerRunnable = new Runnable() {
    @Override
    public void run() {

        if  (bFlagForceExit )
    MyProcessForExit(); 

        if (bSomeflagForRunAction)
            RunProcess();

        timerHandler.postDelayed(this, MILISEGUNDOS_ESPERA);        }
};


private void  MyProcessForExit()
{
    timerHandler.removeCallbacks(timerRunnable);
// close activity or whatever
finish();
}


private void  RunProcess()
{
   // action that i do when tick 
// time to leave or stop
bFlagForceExit = true;
}

后来我发现,如果对其他线程调用removeCallbacks(timerRunnable),这个方法就会起作用,所以我就这样解决了这个问题。

boolean bFlagForceExit = false; 
Handler timerHandler = new Handler();
private   Runnable timerRunnable = new Runnable() {
    @Override
    public void run() {

        if  (bFlagForceExit )
        {
    // add a thred for run your stop handler
            new Thread(new Runnable() {
                public void run() {
                    SalirDeProceso();
                }
            }).start();
        }

        if (bSomeflagForRunAction)
            RUnProcess();

        timerHandler.postDelayed(this, MILISEGUNDOS_ESPERA);        }
};

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