您的当前位置:首页正文

Handler后台空闲线程IdleHandler运行代码示例

来源:图艺博知识网

今天看源码的时候, 忽然对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只在当前事件之后执行.

Top