Android 消息传递机制分析

Android系统出于系统优化的原因,UI线程操作并不是线程安全的,这意味着如果多线程并发操作UI组件,则可能导致线程线程安全。所以为了解决这个问题,Android制定了一条规则:只允许UI线程修改Activity里的UI组件。

当一个程序启动第一次启动时,Android会同时启动一条主线程(Main Thread),主线程负责处理与UI相关的事件,并把相关的事件分发到对应的组件进行处理,所以主线程又称UI线程

Handler类简介

Handler类的主要俩个作用:

1.在新启动的线程中发送消息

2.在主线程中获取,处理消息

Handler类包含常用的用于发送,处理消息。

void handleMessage(Message msg):处理消息的方法,需要被重写

final boolean hasMessage(int what):检查消息队列中是否包含what属性未指定值的消息

final boolean hasMessage(int what ,Object object):检查消息队列中是否包含what属性并且object属性的消息

Message obtainMessage():多个重载,获取消息

final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定多少毫秒后发送空消息

final boolean sendMessage(Message msg):立即发送消息

final boolean sendMessageDelay(Message msg,long delayMillis):指定多少毫秒后发送消息

 

 

Handler,Loop,MessageQueue的工作原理:

Message:Handler接收和处理的消息对象

Looper:每个线程只能拥有一个Looper,负责读取MessageQueue中的消息,读到消息之后交给发送该消息的Handler进行处理

MessageQueue:消息队列,采用先进先出的管理方式来管理Message。创建Looper对象时,会在它的构造器中创建MessageQueue对象。

 

Looper的构造器源码:

private Looper(){

mQueue=new MessageQueue();

mRun=true;

mThread=Thread.currentThread();
}

 

为了保证保证每个线程中最多只有一个Looper对象。所以可以使用prepare()方法,码源如下:

public static final void prepare(){
if(sThreadLocal.get()!=nul){

throw new RuntimeException(“Only one Looper may be created per thread”);

}

sThreadLocal.set(new Looper());
}

 

接下来就可以调用Looper的静态loop()方法来启动它。loop()方法是个死循环不断地1取出小,并交给对应的Handler进行处理。

Loop()的相关源代码:

for(;;){
Message msg=queue.next();//获取下一个消息,如果没有消息将会阻塞

if(msg==null){
return;//消息队列正在退出

}

Printer logging=me.mlogging;

if(logging!=null){

logging.println(“>>>>> Dispatching to”+msg.target +" "+msg.callback + ":" +msg.what);

}

msg.target.dispatchMessage(msg);

if(logging!=null){
logging.println("<<<<< Finished to" +msg.target +" " +msg.callback);
}

final long newIdent =Binder.clearCallingIdentity();

if(ident !=newIdent){
log.wtf(TAG,"Thread identity changed from 0x"

+ Long.toHexString(ident) + "to 0x"

+Long.toHexString(newIdent) + "while dispatching to"

+msg.target.getClass().getName() +" "

+msg.callback +"what=" +msg.what);
}
msg.recycle();
}

 

使用步骤:

调用Looper的preapare()为当前线程创建消息管理队列

有了Looper之后,创建Handler子类的实例,重写handleMessage()方法,处理来自其他线程的消息

调用Looper的loop()方法启动Looper

你可能感兴趣的:(Android 消息传递机制分析)