zoukankan      html  css  js  c++  java
  • android Handler 机制研究学习笔记

    前言: 很早以前,学习android的时候就接触过Handler ,知道Handler是一个用于线程间通信的类,最常用于做下载条,最近,看了Pro android 3 这本书,里面描述的Handler 说得非常的细致,与此,写下Handler的学习笔记

    Android 运行的进程

      为了,更好的了解Handler的机制,我们应该首先,将Android系统整个运行进程都要烂熟于心,下面是android 进程运行图:

    androidProcess 

    从图中我们可以看到,当我们从外部调用组件的时候,Service 和 ContentProvider 是从线程池那里获取线程,而Activity 和BroadcastReceiver是直接在主线程运行,为了,追踪线程,我们可以用debug 方法,或者使用一个工具类,这里,我们创建一个用于监视线程的工具类

    /**
     * @author Tom_achai
     * @date 2011-11-20
     * 
     */
    public class Utils {
    	public static long getThreadId(){
    		Thread t = Thread.currentThread();
    		return t.getId();
    	}
    	
    	/**
    	 * 获取单独线程信息
    	 * @return
    	 */
    	public static String getThreadSignature(){
    		Thread t = Thread.currentThread();
    		long l = t.getId();
    		String name = t.getName();
    		long p = t.getPriority();
    		String gname = t.getThreadGroup().getName();
    		return ("(Thread):"+name+":(id)"+ l +"(:priority)" + p + ":(group)" + gname );
    	}
    	
    	
    	
    	/**
    	 *获取当前线程 信息
    	 */
    	public static void logThreadSignature(){
    		Log.d("ThreadUtils", getThreadSignature());
    	}
    	
    	public static void logThreadSignature(String name ){
    		Log.d("ThreadUtils", name + ":"+getThreadSignature());
    	}
    	
    	public static void sleepForInSecs(int secs){
    		try{
    			Thread.sleep(secs * 1000);
    		}catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 讲String放进Bundle 中
    	 * @param message
    	 * @return
    	 */
    	public static Bundle getStringAsBundle(String message){
    		Bundle b = new Bundle();
    		b.putString("message", message);
    		return b;
    	}
    	
    	/**
    	 * 
    	 * 获取Bundle的String
    	 * @param b
    	 * @return
    	 */
    	public static String getStringFromABundle(Bundle b){
    		return b.getString("message");
    	}
    }

    有了这样一个类就可以方便我们观察线程的运行

    好了,现在准备好以后就进入正题Handler

    Handlers

    为什么要使用Handlers?

        因为,我们当我们的主线程队列,如果处理一个消息超过5秒,android 就会抛出一个 ANP(无响应)的消息,所以,我们需要把一些要处理比较长的消息,放在一个单独线程里面处理,把处理以后的结果,返回给主线程运行,就需要用的Handler来进行线程建的通信,关系如下图;

         mainthread

    下面是Handler,Message,Message Queue 之间的关系图

    Handlers

    这个图有4个地方关系到handlers

    1, 主线程(Main thread)

    2, 主线程队列(Main thread queue)

    3,Hanlder

    4,Message

       上面的四个地方,主线程,和主线程的队列我们无需处理,所以,我们主要是处理Handler 和 Message 之间的关系.

       我们每发出一个Message,Message就会落在主线程的队列当中,然后,Handler就可以调用Message绑定的数据,对主线程的组件进行操作.

    Message

    作为handler接受的对象,我们有必要知道Message这个数据类型是个怎样的数据类型

    从官方文档中我们可以知道message 关于数据的字段

       
    public int what  
    public int arg1  
    public int arg2  
    public Object obj  

    从上面的表格可以看出,message 提供了一个对象来存储对象,而且,还提供了三个int字段用来存储少量int类型

    当然,除了以上三个Message 自有的字段外,我们还可以通过setData(Bundle b),来存储一个Bundle对象,来存储更丰富的数据类型,例如,图片等等.

    在初始化我们的message的时候就可以为我们的Message默认字段赋值,注意赋值顺序!!!

    Message msg = obtainMessage();
    //设置我们what 字段的初值,注意顺序!!!
    Message msg = mHandler.obtainMessage(int what);
    
    //下面同理
    Message msg = mHandler.obtainMessage(int what,Object object);
    Message msg = mHandler.obtainMessage(int what,int arg1,int arg2);
    Message msg = mHandler.obtainMessage(int what,int arg1,int arg2, Object obj
    );

  • 相关阅读:
    2021 Duilib最新入门教程(二)Duilib编译动态库
    2021 Duilib最新入门教程(一)Duilib简介
    webgl图库选型
    CUDA编程学习记录
    C++时间戳获取
    FFMPEG编译问题记录
    程序员的35岁
    Linux发行版及其目标用户
    服务器关机或重启
    Linux下找出吃内存的方法总结
  • 原文地址:https://www.cnblogs.com/youxilua/p/2263825.html
Copyright © 2011-2022 走看看