Handler.post不执行

Posted 爱炒饭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Handler.post不执行相关的知识,希望对你有一定的参考价值。

使用HandlerThread的Looper创建一个Handler的对象mIoHandler,然后通过点击事件go触发该mIoHandler的post方法去执行一个Runnable,该Runnable会持有锁等待直到被唤醒(模拟耗时操作),点击事件undo则可以试下唤醒锁等待的功能,代码如下

mIoHandlerThread = new HandlerThread("io");
mIoHandlerThread.start();
mIoHandler = new Handler(mIoHandlerThread.getLooper());

public void go(View view) 
    Log.d(TAG, "go: ");
    mIoHandler.post(new Runnable() 
        @Override
        public void run() 
            Log.d(TAG, "run: ");
            synchronized (mObject)
                try 
                    Log.d(TAG, "run: 1");
                    mObject.wait();
                    Log.d(TAG, "run: 2");
                 catch (InterruptedException e) 
                    e.printStackTrace();
                    Log.e(TAG, "run: InterruptedException e="+e.getMessage());
                
            
        
    );


public void undo(View view) 
    Log.d(TAG, "undo: ");
    synchronized (mObject)
        Log.d(TAG, "undo: 1");
        mObject.notifyAll();
        Log.d(TAG, "undo: notifyAll");
    

第一次执行go方法去执行mIoHandler.post时Runnable内部的run方法执行了并且开始等待,第二次执行go方法时Runnable内部的run方法就不执行了,只有通过undo则唤醒锁等待才可以接续执行,log打印如下

2021-11-23 19:33:21.925 29370-29370/com.shan.unittestapp D/zzzzz_Ap: go: 
2021-11-23 19:33:21.926 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 
2021-11-23 19:33:21.926 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 1
2021-11-23 19:33:46.290 29370-29370/com.shan.unittestapp D/zzzzz_Ap: go: 
2021-11-23 19:33:50.487 29370-29370/com.shan.unittestapp D/zzzzz_Ap: go: 
2021-11-23 19:33:52.812 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: 
2021-11-23 19:33:52.812 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: 1
2021-11-23 19:33:52.812 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: notifyAll
2021-11-23 19:33:52.813 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 2
2021-11-23 19:33:52.814 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 
2021-11-23 19:33:52.814 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 1
2021-11-23 19:34:07.538 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: 
2021-11-23 19:34:07.538 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: 1
2021-11-23 19:34:07.538 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: notifyAll
2021-11-23 19:34:07.539 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 2
2021-11-23 19:34:07.540 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 
2021-11-23 19:34:07.540 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 1
2021-11-23 19:34:17.181 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: 
2021-11-23 19:34:17.181 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: 1
2021-11-23 19:34:17.181 29370-29370/com.shan.unittestapp D/zzzzz_Ap: undo: notifyAll
2021-11-23 19:34:17.181 29370-29429/com.shan.unittestapp D/zzzzz_Ap: run: 2

可以看到notifyAll与run: 2是一一对应的,这就说明mIoHandler的MessageQueue将Runnable请求一个个的插入到了MessageQueue中,然后一个执行完再取出一下个去执行。
查看Handler构造函数可以发现,默认是同步的,并且指定looper构造参数的构造函数必须同步(第三个参数表示异步,为false)。

/**
 * Use the provided @link Looper instead of the default one and take a callback
 * interface in which to handle messages.
 *
 * @param looper The looper, must not be null.
 * @param callback The callback interface in which to handle messages, or null.
 */
public Handler(@NonNull Looper looper, @Nullable Callback callback) 
    this(looper, callback, false);

只有单独下面构造函数才可以在当前线程创建异步Handler


/**
 * Use the @link Looper for the current thread
 * and set whether the handler should be asynchronous.
 *
 * Handlers are synchronous by default unless this constructor is used to make
 * one that is strictly asynchronous.
 *
 * Asynchronous messages represent interrupts or events that do not require global ordering
 * with respect to synchronous messages.  Asynchronous messages are not subject to
 * the synchronization barriers introduced by @link MessageQueue#enqueueSyncBarrier(long).
 *
 * @param async If true, the handler calls @link Message#setAsynchronous(boolean) for
 * each @link Message that is sent to it or @link Runnable that is posted to it.
 *
 * @hide
 */
@UnsupportedAppUsage
public Handler(boolean async) 
    this(null, async);

以上是关于Handler.post不执行的主要内容,如果未能解决你的问题,请参考以下文章

Handler.post不执行

Handler.post不执行

不频繁的 Handler.post 导致大量丢帧和崩溃

从Handler.post(Runnable r) ,Handler.sendEmptyMessage()梳理Android的消息机制(以及handler的内存泄露)

dialog延迟显示,被activity覆盖不显示

执行代码时有时不显示对话框片段