我们来看一个简单的代码:
package com.mly.panhouye.handlerdemo; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.TextView; /** * Handler: * 1 处理的消息对象就是Message,理解为要传递的消息数据的封装对象 * Message what : 标记,用来区分多个消息 * Message arg1,arg2 : 用来传递int类型的数据 * Message obj : 可以传递任何类型的对象(Object) */ public class Main2Activity extends AppCompatActivity { public static final int UPDATE = 0x1; TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); tv = (TextView) findViewById(R.id.tv); begin();//开启倒计时并跳转页面的方法 } //消息处理者,创建一个Handler的子类对象,目的是重写Handler的处理消息的方法(handleMessage()) private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case UPDATE: tv.setText(String.valueOf(msg.arg1)); break; } } }; public void begin(){ new Thread(new Runnable() { @Override public void run() { for (int i=5;i>0;i--){ Message msg = new Message(); msg.what = UPDATE; msg.arg1 = i; handler.sendMessage(msg); try { Thread.sleep(1000);//休眠1秒 } catch (InterruptedException e) { e.printStackTrace(); } //打印log Log.i("tag",Main2Activity.this+"-"+ i); } //计时结束后跳转到其他界面 startActivity(new Intent(Main2Activity.this,Main3Activity.class)); //添加finish方法在任务栈中销毁倒计时界面,使新开界面在回退时直接退出而不是再次返回该界面 finish(); } }).start(); } @Override protected void onDestroy() { super.onDestroy(); //log打印用于测试activity销毁 Log.i("tag","destory"); } }
首先在主线程中创建handler对象,然后再子线程中调用handle的sendmsg方法,然后再handlemessage中收到消息之后更新UI
我们来分析下handle的详细流程
首先主线程创建的时候会创建调用Loop.prepare()函数,该函数主要做下面的两件事情
1、创建一个looper对象,该对象有一个成员变量,该成员变量就是一个消息队列
2、使用threadlocal将该looper对象和当前的主线程绑定。
在 创建一个handler对象的时候,主要做了下面的操作
通过threadlocal的get方法,得到保存到里面的looper对象,通过looper对象就可以获得looper的成员变量就是消息队列
在子线程中调用handler.sendMsg的时候
就是将当前的消息添加到消息队列中,当前的消息有个成员变量就是创建的handle对象
消息的有个属性是target属性,该属性的值this就是当前的handler对象。
执行handle.sendMessage之后会在主线程操作系统会执行
Loop.loop()函数,该函数执行下面的操作
首先获得looper对象,就获得了消息队列,然后开启一个死循环变量消息队列中的所有消息,从消息队列中获得所保存的消息
得到消息之后调用msg.target.dispatchMessage(msg)方法
我们上面知道msg.target对象就是handle对象,在Loop.loop()中实际上就是调用了handle对象的dispatchMessage(msg)方法
handle对象的dispatchMessage(msg)的内部调用了handleMessage的方法
所以实际上Loop.loop()函数实际上是调用了handle.handleMessage(msg)方法,相当的经典