Runnable发布在另一个runnable中未执行

时间:2014-06-11 20:52:32

标签: android multithreading handler runnable

我正在尝试使用我的单例的Handler.post()方法从另一个runnable运行runnable,但是在原始runnable完成之后才会运行第二个runnable。在下面的示例代码中,我从应用程序的某个位置调用MyManager,getInstance()。startCommand()。 MyCommand类中的myRun变量在线程上有一个睡眠,所以我可以测试一个超时功能,但是在myRun runnable完成之后才会执行名为mTimeoutTimer的runnable。为什么会发生这种情况,我该如何改变呢?

public class MyManager{
    private MyManager sInstance;
    private Handler mHandler;
    private Runnable mTimeoutTimer;

    public static MyManager getInstance(){
        if(sInstance == null){
            sInstance = new MyManager();
        }
        return sInstance;
    }

    private MyManager(){
        mHandler = new Handler();
        mTimeoutTimer = new Runnable() {
        @Override
        public void run() {
            Log.e(“RUNNABLE RUNNING!”);
        }
    };

    public class MyCommand {
       private Runnable myRun;

       public MyCommand(){
           myRun = new Runnable() {
               @Override
               public void run() {
                   MyManager.getInstance().startTimeoutTimer();

                   try {
                       Thread.sleep(COMMAND_TIMEOUT_MILLIS * 3);
                   } catch (InterruptedException e) {}

                   MyCommand.this.execute();
               }
           };
       }

       public void execute() {
           myRun.run();
       }
    }


    private void startTimeoutTimer(){
        mHandler.postDelayed(mTimeoutTimer);
    }


    public void startCommand(){
        new MyCommand().execute();
    }
}

2 个答案:

答案 0 :(得分:2)

这是因为在主线程中调用了Handler,所以它将等待另一个完成

而是将您的其他处理程序放在HandlerThread中以在单独的线程上运行处理程序

    HandlerThread thread = new HandlerThread("HandlerThread");
    thread.start();
    Handler handler = new Handler(thread.getLooper());

HandlerThread

的文档
  Handy class for starting a new thread that has a looper.
  The looper can then be used to create    handler classes. 
  Note that start() must still be called.

答案 1 :(得分:1)

一个线程不能一次执行两个Runnables(或者任何一次两个,真的)。

如果将两者都发布到绑定到同一线程(通常是UI线程)的Handler个实例,则必须等待另一个完成。

要在另一个主题中运行,请使用

new Thread(mTimeoutTimer).start();

或者您可以使用线程池。请参阅documentation