Android Handler 源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WAngyouWei_0/article/details/80367236

❤❤❤:


简单的分析一下

因为子线程不能修改主线程的UI(非特殊情况),因此子线程需要通过Handler通知主线程修改UI,进行线程间通信。

首先讲,Handler有四个关键的对象就是 Message,MessageQueue,Lopper,Handler

下面是一段基本用法

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private String TAG = "MainActivity";
    private int i = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
    }
    public void onClick(View v){
        ++i;
        //创建新的线程
        new Thread(){
            @Override
            public void run() {
                super.run();
                doSendMsg();
            }
        }.start();
    }

    /**
     * 在子线程中做耗时操作,完成之后,通知Handler更新UI
     */
    private void doSendMsg(){
        try {
            Thread.sleep(1000);//模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Message message = Message.obtain();
        message.arg1 = i;
        message.what = 1;
        mHandler.sendMessage(message);
    }

    Handler mHandler = new Handler(){
        /**
         * handleMessage接收消息后进行相应的处理
         * @param msg
         */
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what==1){
                textView.setText(msg.arg1+"");
            }
        }
    };
}

MessageQueue

MessageQueue源码链接

一个Message就是线程需要处理的一件事情,MessageQueue就是一个处理Message的池,在MessageQueue里面有removeIdleHandler()方法,移除空闲的线程

enqueueMessage() 是将Message放入消息队列当中

next() 方法当中有一个for循环,不断地从消息队列中阻塞式的取出一个Message

Lopper

Looper源码链接

Lopper是用来使线程当中的消息循环起来,当创建新线程的时候是没有MessageQueue的,首先要调用Lopper的prepare,然后调用loop。这两个方法都是在线程的run方法里面调用,一个线程最多有一个Lopper

ThreadLocal保存了对当前线程的引用,set方法向ThreadLocal里面传一个Looper,get方法从TreadLocal中取出一个Looper

prepare方法当中如果 threadlocal的get()方法不!=null就抛出异常 如果等于空就会执行set方法绑定Lopper

Lopper的构造方法当中实例化了MessageQueue,进行了关联

执行完prepare方法之后就会执行 my'Lopper方法,会告知我们只能有一个Lopper

loop()方法中首先获得当前的线程所绑定的Looper,如果没有绑定的Looper就会报一个异常,如果绑定执行下面的代码,有一个死循环,不断调用MessageQueue的next()方法从队列中取出message,然后让Handel去处理该Message。

Handler:

Handler源码链接

本身有4个构造方法

1. publicHandler() 

2. publicHandler(Callbackcallback) 

3. publicHandler(Looperlooper) 

4. publicHandler(Looperlooper, Callbackcallback) 

传递的Callback是一个内部接口,重写了handleMessage()方法

sendMessage可以向消息队列中添加消息,sendMessage调用了sendMessageDelayed,sendMessageDelayed又调用了sendMessageAtTime

sendEmptyMessage也是如此

postMessage依赖于sendMessage,区别在于post携带runnable

sendMessageAtTime方法当中调用了enqueueMessage将消息放入消息队列

猜你喜欢

转载自blog.csdn.net/WAngyouWei_0/article/details/80367236