Handler和HandlerThread总结

2017-09-17  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读