zoukankan      html  css  js  c++  java
  • 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)方法,相当的经典

  • 相关阅读:
    GitHub挂载网站
    JS中用execCommand("SaveAs")保存页面兼容性问题解决方案
    使用List,Dictionary加载数据库中的数据
    模拟在table中移动鼠标,高亮显示鼠标所在行
    ASP.NET AutoCompleteType 属性,这么多年的IT人你发现了吗?
    生成流水号
    在数据库中查找字符串(不知道表名的情况下 查找字符串)
    半角与全角之间的转换
    C#代码规范精简表
    有关Excel导出
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7209054.html
Copyright © 2011-2022 走看看