}
finallongnewIdent=Binder.clearCallingIdentity();
if(ident!
=newIdent){
Log.wtf(TAG,"Threadidentitychangedfrom0x"
+Long.toHexString(ident)+"to0x"
+Long.toHexString(newIdent)+"whiledispatchingto"
+msg.target.getClass().getName()+""
+msg.callback+"what="+msg.what);
}
//释放消息占据的资源
msg.recycle();
}
}
总结Looper的作用:
1.实例化本身、与当前线程绑定、创建与之相应的MessageQueue:
prepare()方法
一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue
消息循环(消息取出、消息派发):
loop()方法
不断从MessageQueue中去取消息,派发给消息的target属性的Handler,然后调用相应Handler的dispatchMessage()方法进行消息处理。
第二部分:
Handler
主要负责:
1.在子线程发送消息给MessageQueue2.处理Looper派发过来的消息使用Handler之前,会初始化一个Handler实例
Handler是需要和线程绑定在一起的,在初始化Handler的时候一般通过指定Looper对象从而绑定相应线程,即给Handler指定Looper对象=绑定到了Looper对象所在的线程中,Handler的消息处理回调会在那个线程中执行。
一般有两种方法创建:
1.通过Loop.myLooper()得到当前线程的Looper对象/通过Loop.getMainLooper()可以获得当前进程的主线程的Looper对象。
2.不指定Looper对象,那么这个Handler绑定到了创建这个线程的线程上,消息处理回调也就在创建线程中执行.
首先看Handler的构造方法
publicHandler(){
this(null,false);
}
publicHandler(Callbackcallback,booleanasync){
if(FIND_POTENTIAL_LEAKS){
finalClass
extendsHandler>klass=getClass();
if((klass.isAnonymousClass()||klass.isMemberClass()||klass.isLocalClass())&&
(klass.getModifiers()&Modifier.STATIC)==0){
Log.w(TAG,"ThefollowingHandlerclassshouldbestaticorleaksmightoccur:
"+
klass.getCanonicalName());
}
}
//通过Looper.myLooper()获取了当前线程保存的Looper实例,如果线程没有Looper实例那么会抛出异常
//这说明在一个没有创建Looper的线程中是无法创建一个Handler对象的
//所以说我们在子线程中创建一个Handler时首先需要创建Looper,并且开启消息循环才能够使用这个Handler。
mLooper=Looper.myLooper();
if(mLooper==null){
thrownewRuntimeException(
"Can'tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()");
}
//获取了这个Looper实例中保存的MessageQueue(消息队列)
//这样就保证了handler的实例与我们Looper实例中MessageQueue关联上了
mQueue=mLooper.mQueue;
mCallback=callback;
mAsynchronous=async;
}
上述说明:
当Handler初始化时,可通过构造方法自动关联Looper和相应的MessageQueue
1.Handler向MessageQueue发送消息:
对于Handler的发送方式可以分为post和send两种方式。
send的发送方法:
sendMessage()
publicfinalbooleansendMessage(Messagemsg)
{
returnsendMessageDelayed(msg,0);
}
//我们往下扒
publicfinalbooleansendEmptyMessageDelayed(intwhat,longdelayMillis){
Messagemsg=Message.obtain();
msg.what=what;
returnsendMessageDelayed(msg,delayMillis);
}
publicfinalbooleansendMessageDelayed(Messagemsg,longdelayMillis)
{
if(delayMillis<0){
delayMillis=0;
}
returnsendMessageAtTime(msg,SystemClock.uptimeMillis()+delayMillis);
}
publicbooleansendMessageAtTime(Messagemsg,longuptimeMillis){
//直接获取MessageQueue
MessageQueuequeue=mQueue;
if(queue==null){
RuntimeExceptione=newRuntimeException(
this+"sendMessageAtTime()calledwithnomQueue");
Log.w("Looper",e.getMessage(),e);
returnfalse;
}
//调用了enqueueMessage方法
returnenqueueMessage(queue,msg,uptimeMillis);
}
//调用sendMessage方法其实最后是调用了enqueueMessage方法
privatebooleanenqueueMessage(MessageQueuequeue,Messagemsg,longuptimeMillis){
//为msg.target赋值为this,也就是把当前的handler作为msg的target属性
//如果大家还记得Looper的loop()方法会取出每个msg然后执行msg.target.dispatchMessage(msg)去处理消息,其实就是派发给相应的Handler
msg.target=this;
if(mAsynchronous){
msg.setAsynchronous(true);
}
//最终调用queue的enqueueMessage的方法,也就是说handler发出的消息,最终会保存到消息队列中去。
returnqueue.enqueueMessage(msg,uptimeMillis);
}
Post的发送方法:
sendMessage()
showhandler.post(newRunnable(){
@Override
publicvoidrun(){
Stringline="\n";
StringBuffertext=newStringBuffer(show.getText());
text.append(line).append("angelababy:
Yes,Ido");
show.setText(text);
}
相比send方法,post方法最大的不同在于,更新UI操作可直接在重写的run方法定义。
其实Runnable并没有创建什么线程,而是发送了一条消息,下面看源码:
publicfinalbooleanpost(Runnabler)
{
returnsendMessageDelayed(getPostMessage(r),0);
}
privatestaticMessagegetPostMessage(Runnabler){
//创建了一个Message对象
//创建Message对象可以new,也可以使用Message.obtain()方法;
//但是更建议使用obtain方法,因为Message内部维护了一个Message池用于Message的复用,避免使用new重新分配内存。
Messagem=Message.obtain();
//将我们创建的Runable对象作为callback属性,赋值给了此message.
m.callback=r;
//创建了一个Message对象
returnm;
}
publicfinalbooleansendMessageDelayed(Messagemsg,longdelayMillis)
{
if(delayMillis<0){
delayMillis=0;
}
returnsendMessageAtTime(msg,SystemClock.uptimeMillis()+delayMillis);
}
publicbooleansendMessageAtTime(Messagemsg,longuptimeMillis){
MessageQueuequeue=mQueue;
if(queue==null){
RuntimeExceptione=newRuntimeException(
this+"sendMessageAtTime()calledwithnomQueue");
Log.w("Looper",e.getMessage(),e);
returnfalse;
}
returnenqueueMessage(queue,msg,uptimeMillis);
}
从上面的源码发现了吧?
和send中的handler.sendMessage是一样的。
调用了sendMessageAtTime,然后调用了enqueueMessage方法,给msg.target赋值为handler,最终Handler将消息加入MessagQueue.
但是细心的你会发现,在使用Post方法时会将我们创建的Runable对象作为callback属性赋值给了此message
那么msg的callback和target都有值,那么会执行哪个呢?
我们已知回调发送消息的方法是:
dispatchMessage()
publicvoiddispatchMessage(Messagemsg){
//一开始就会进行判断
//如果msg.callback属性不为null,则执行callback回调,也就是我们的Runnable对象
if(msg.callback!
=null){
handleCallback(msg);
}else{
if(mCallback!
=null){
if(mCallback.handleMessage(msg)){
return;
}
}
handleMessage(msg);
}
}
####2.处理Looper派发过来的消息:
dispathMessage()方法
publicvoiddispatchMessage(Messagemsg){
if(msg.callback!
=null){
handleCallback(msg);
}else{
if(mCallback!
=null){
if(mCallback.handleMessage(msg)){
return;
}
}
handleMessage(msg);
}
}
publicvoidhandleMessage(Messagemsg){
}
可以看到dispathMessage()方法里调用了handleMessage()方法,但handleMessage()是一个空方法
因为Handler发送消息过来是希望进行一定的处理,至于怎么处理消息是该Handler最终控制的,所以我们在创建handler时需要通过复写handleMessage()方法从而实现我们需要的消息处理方式,然后根据msg.what标识进行消息处理。
这就是为什么我们在主线程中实例化Handler的时候需要重写handleMessage()
特别注意
在一个Android应用启动的时候,会创建一个主线程,即ActivityThread(也叫UI线程),在ActivityThread中有一个静态的main方法:
应用程序的入口点
//一个进程会默认生成一个主线程
publicstaticvoidmain(String[]args){
......
//主线程生成时自动通过prepareMainLooper方法为主线程创建一个Looper
//prepare()方法是用于在子线程中创建一个Looper对象,在子线程中是可以退出消息循环的:
调用消息队列的quit方法
//Looper生成时会自动生成与之配套的消息队列
Looper.prepareMainLooper();
ActivityThreadthread=newAct