先由线程说起Thread,线程创建时,为了能够使得线程有一个工作函数,一般有2种方法:重写run方法和创建线程时指定一个实现了Runnable接口的对象实例,当然也可以同时实现这2种方法,因为在Thread类中run方法实现如下
@Override public void run() { if (target != null) { target.run(); } }
而且中的target就是一个Runnable对象。
loop是一个循环体,那么问题来了,循环体,为什么可以循环,在android中一般是一个app启动,最简单的情况就启动进程,在进程创建的同时伴随着一个主线程启动,就是UIthread。在这个ui线程的就是一个消息驱动的工作线程,既然有消息驱动那么对应的消息循环loop,消息发送的handler,和消息体message就需要相互配合了。
framework/base/services/java/com/android/server/am/ActivityManagerService.java在这个文件可以看到相关代码
这个loop类,在实现中有很多静态方法,uithread创建的时候,首先第一步就通过Looper.prepare();方法为当前线程创建looper,并且在线程最后启动这个looper. 这里uithread的looper就有了,
接着继续找handler对象,handler对象的创建,直接new handler,重写了handleMessage方法。这样创建并没有将loop和handler关联上,那么handler怎么知道我的消息该发往哪里?看一眼handler的构造函数,可以在handler的构造函数发想Looper.myLooper(),这个方法获取当前线程对应的loop,将loop中的消息队列获得,以后发送消息的时候,就直接吧消息往消息队列里面放就可以了。handler有了,消息也可以发给loop了
因此一般情况下,使用创建handler的时候,如果不指定loop,那么处理消息的线程就是创建消息的线程。
如果需要消息不在uithread中处理,那么就需要创建新的线程,在线程的run方法运行起来后,需要在run方法中创建looper,并且启动这个looper, 并且保存这个looper的引用;构造handler的时候使用这个loop作为构造函数参数,完成handler构造,使用handler发消息,就可以发送到指定线程了。
需要理解的是线程启动本身没有loop,有一个线程函数run执行,如果创建loop,并运行,因为loop里面存在一个死循环,一直处理消息队列,没消息就等待,有就处理,因此线程会一直在Looper.loop()这个函数运行。
我看了下thread和loop的对应关系存放在ThreadLocal