【问题标题】:Android: How do I stop Runnable?Android:如何停止 Runnable?
【发布时间】:2012-03-16 12:25:03
【问题描述】:

我试过这样:

private Runnable changeColor = new Runnable() {
   private boolean killMe=false;
   public void run() {
       //some work
       if(!killMe) color_changer.postDelayed(changeColor, 150);
   }
   public void kill(){
       killMe=true;
   }
};

但我无法访问kill() 方法!

【问题讨论】:

    标签: android runnable


    【解决方案1】:

    changeColor 被声明为Runnable,它没有kill() 方法。

    您需要创建自己的接口,扩展Runnable 并添加(公共)kill() 方法。

    【讨论】:

    • 如果我创建一个新类,那么编译器会说“color_changer.postDelayed(changeColor, 150);”有问题- changeColor 无法解析为变量。
    • 否;我是说界面。但是,创建一个非匿名类也可以。你的意思是this
    • 非匿名类@SLaks 到底是什么意思
    • @Dr.aNdRO:我的意思是一个普通的命名类,而不是一个匿名类。
    【解决方案2】:

    改为使用 SDK 提供的现有 API 实现您自己的 thread.kill() 机制。在threadpool 中管理您的线程创建,并使用Future.cancel() 终止正在运行的线程:

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Runnable longRunningTask = new Runnable();
    
    // submit task to threadpool:
    Future longRunningTaskFuture = executorService.submit(longRunningTask);
    
    ... ...
    // At some point in the future, if you want to kill the task:
    longRunningTaskFuture.cancel(true);
    ... ...
    

    Cancel 方法的行为会根据您的任务运行状态而有所不同,请查看 API 了解更多详细信息。

    【讨论】:

    • 如果longRunningTask 包含任务列表,我如何中止某些任务的执行?可能有很多线程同时运行。
    • @DanielWilson 我也有同样的问题。你解决了吗?
    • .cancel 方法未找到
    • @Alston 这是可能的,但您需要跟踪参考资料。由于void run() 的返回值,列表不起作用。集合不存储 null。当您 submit(Runnable) 它们时,您可能会使用 Map<Runnable, Future<?> 来累积对每个 Runnable 的引用。或者,您可以使用 Callable+Collection,因为 Callable 可以返回 null 以外的内容。
    【解决方案3】:
    public abstract class StoppableRunnable implements Runnable {
    
        private volatile boolean mIsStopped = false;
    
        public abstract void stoppableRun();
    
        public void run() {
            setStopped(false);
            while(!mIsStopped) {
                stoppableRun();
                stop();
            }
        }
    
        public boolean isStopped() {
            return mIsStopped;
        }
    
        private void setStopped(boolean isStop) {    
            if (mIsStopped != isStop)
                mIsStopped = isStop;
        }
    
        public void stop() {
            setStopped(true);
        }
    }
    

    类......

        private Handler mHandler = new Handler();
    
    public void onStopThread() {
        mTask.stop();       
        mHandler.removeCallbacks(mTask);
    }
    
    public void onStartThread(long delayMillis) {
        mHandler.postDelayed(mTask, delayMillis);
    }
    
    private StoppableRunnable mTask = new StoppableRunnable() {
        public void stoppableRun() {        
                        .....
                onStartThread(1000);                
            }
        }
    };
    

    【讨论】:

    • 你是否意识到这个实现会让你的 Runnable 消耗 CPU 周期?
    【解决方案4】:
    mHandler.removeCallbacks(updateThread);
    

    【讨论】:

    • 请尝试描述答案
    • 这对我来说是最简单的方法。
    • 实际上,这似乎是正确的答案,因为您不必使用其中的所有 yada-yada 创建自己的自定义 Runnable 或使用 ExecutorService。这就是removeCallbacks 方法的用途。它最接近 JavaScript clearTimeout,模式相同。
    • 这只会取消已发布到线程队列的待处理可运行文件。它不会停止已经在运行的 runnables。
    【解决方案5】:

    你可以这样使用

    停止可运行线程 //================================================= ===============================

     ThreadUtil.startTask(() -> {
                            // doTask
                        }, 1500);
    
    
    //==============================================================================
     public class ThreadUtil {
    
            private static Handler handler;
            private static Runnable runnable;
    
            public static void startTask(IThreadTask iThreadTask, long delayTime) {
                stopTask();
                handler = new Handler();
                runnable = () -> {
                    iThreadTask.doTask();
                };
    
                if (handler == null || runnable == null) {
                    return;
                }
    
                handler.postDelayed(runnable, delayTime);
    
            }
    
            public static void stopTask() {
                try {
                    handler.removeCallbacks(runnable);
                    handler.removeCallbacksAndMessages(null);
                    handler = null;
                    runnable = null;
    
                }catch (Exception e){
                    Log.e("ThreadUtil:","Error:"+e.toString());
    
                }
    
            }
    
    
            public interface IThreadTask {
                void doTask();
            }
    
    
        }
    

    【讨论】:

      猜你喜欢
      • 2013-09-11
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 2016-03-07
      相关资源
      最近更新 更多