今天看源码的时候, 忽然对idleHandler的运行逻辑有点含糊了.
写了一个示例, 加深一下印象.
public class EmptyActivity extends Activity {
private static final String TAG = "EmptyActivity.TAG";
private static int idleHandlerRunCount = 0;
private Handler mainHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "handleMessage: msg:" + msg.what);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_empty);
Log.d(TAG, "onCreate: ....");
TextView btn = findViewById(R.id.event_tv);
btn.setOnClickListener(v -> {
Log.e(TAG, "点击了TextView....");
for (int i = 1; i < 5; i++) {
mainHandler.sendEmptyMessage(i);
}
});
Looper.myQueue().addIdleHandler(new RunOnceHandler());
Looper.myQueue().addIdleHandler(new KeepAliveHandler());
}
class KeepAliveHandler implements MessageQueue.IdleHandler {
/**
* 返回值为true,则保持此Idle一直在Handler中
*/
@Override
public boolean queueIdle() {
idleHandlerRunCount++;
Log.d(TAG, "KeepAliveHandler.queueIdle...第" + idleHandlerRunCount + "次运行");
return true;
}
}
class RunOnceHandler implements MessageQueue.IdleHandler {
@Override
public boolean queueIdle() {
Log.d(TAG, "RunOnceHandler.queueIdle()...只运行一次");
return false;
}
}
}
运行代码之后, 触发界面的TextView事件. logcat如下:
07-20 10:11:07.715 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: onCreate: ....
07-20 10:11:07.871 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: RunOnceHandler.queueIdle()...只运行一次
KeepAliveHandler.queueIdle...第1次运行
07-20 10:11:08.103 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: KeepAliveHandler.queueIdle...第2次运行
点击textView之后, logcat如下:
07-20 10:11:07.715 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: onCreate: ....
07-20 10:11:07.871 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: RunOnceHandler.queueIdle()...只运行一次
KeepAliveHandler.queueIdle...第1次运行
07-20 10:11:08.103 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: KeepAliveHandler.queueIdle...第2次运行
07-20 10:11:19.641 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: KeepAliveHandler.queueIdle...第3次运行
07-20 10:11:19.657 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: KeepAliveHandler.queueIdle...第4次运行
07-20 10:11:19.674 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: KeepAliveHandler.queueIdle...第5次运行
07-20 10:11:19.691 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: KeepAliveHandler.queueIdle...第6次运行
07-20 10:11:19.722 7333-7333/com.example.spx.messagetest E/EmptyActivity.TAG: 点击了TextView....
07-20 10:11:19.722 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: handleMessage: msg:1
07-20 10:11:20.224 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: handleMessage: msg:2
07-20 10:11:20.724 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: handleMessage: msg:3
07-20 10:11:21.225 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: handleMessage: msg:4
07-20 10:11:21.727 7333-7333/com.example.spx.messagetest D/EmptyActivity.TAG: KeepAliveHandler.queueIdle...第7次运行
可以看到KeepAliveHandler的运行是有一定不可控的, 它只是在ui线程空闲时触发, 但是什么时候ui线程空闲, 确实很难把握的.
使用时需要注意. 千万不要以为常驻的idlehandler只在当前事件之后执行.