美文网首页
Handler和HandlerThread总结

Handler和HandlerThread总结

作者: 御风逍遥 | 来源:发表于2017-09-17 11:58 被阅读65次

    一般我们使用Hanlder是在子线程和UI线程(主线程)之间传递消息,当Hanlder在UI线程中new出来时候,如果没有显示指定looper的话,会自动绑定当前所在线程即UI线程的Looper,looper管理了一个MessageQueue。其他子线程就可以通过持有该Hanlder的引用,传递消息message,message被放到MessageQueue里面,并被相应handler所绑定线程的looper取出来,在handler的handleMessage()方法里执行相应的处理。handleMessage()所执行的线程就是handler绑定的looper所在的线程。

    UI线程创建时候会自动初始化looper的相关操作,而为子线程创建对应handler则必须手动执行这些步骤。如下:

    Handler mHandler;
    private void createManualThreadWithHandler() {
      new Thread() {
          @Override
            public void run() {
                super.run();
                Looper.prepare();//生成looper
                mHandler = new Handler(Looper.myLooper()) {//显式持有子线程的looper
                    @Override
                    public void handleMessage(Message msg) {
                        //实际的耗时处理任务,在子线程中运行
                    };
                Looper.loop();//不断查询是否有消息进来,此处是死循环
            }
        }.start();
    }
    

    子线程收到消息后实际任务处理在handleMessage中执行。

    HandlerThread实际就是一个Thread,为了方便我们为其创建handler,就在run方法里做了Looper的相应初始化操作,源码如下:

    //调用 start() 后就会执行的 run()
    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();            //帮我们创建了 Looepr
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();    //Looper 已经创建,唤醒阻塞在获取 Looper 的线程
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();    
        Looper.loop();        //开始循环
        mTid = -1;
    }
    

    对HandlerThread我们就可以这样为其创建handler,省去了looper的准备工作:

    HandlerThread handlerThread = new HandlerThread("name");
    handlerThread.start();
    Handler threadHanler = new Handler(handlerThread.getLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //do something
            //此处代码实际运行在子线程:handlerThread
        }
    };
    

    当然,也可以通过在重新的onLooperPrepared()方法来创建handler:

    class MyHandlerThread extends HandlerThread {
        Handler mHandlerThreadHandler;
        public MyHandlerThread(String name) {
            super(name);
        }
    
        @Override
        protected void onLooperPrepared() {
            super.onLooperPrepared();
            mHandlerThreadHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    SystemClock.sleep(2000);//模拟耗时操作
    
                    Toast.makeText(MainActivity.this, "handlerThread:" + msg.obj, Toast.LENGTH_SHORT).show();
                    super.handleMessage(msg);
                }
            };
        }
    }
    

    参考:

    http://blog.csdn.net/u011240877/article/details/72905631

    http://droidyue.com/blog/2015/11/08/make-use-of-handlerthread/index.html

    http://blog.csdn.net/lmj623565791/article/details/47079737

    相关文章

      网友评论

          本文标题:Handler和HandlerThread总结

          本文链接:https://www.haomeiwen.com/subject/fzvpsxtx.html