android handle详解

我们来看一个简单的代码:

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)方法,相当的经典

原文地址:https://www.cnblogs.com/kebibuluan/p/7209054.html