Android多线程
一、消息机制
1.概要
Android应用启动时会有一个默认的主线程(UI线程),主线程中关联一个消息队列,所有操作都被封装成消息交给主线程处理,将获取消息的操作放在死循环中。
开启子线程执行耗时操作后,发消息(sendMessage(msg)或者post Runnable(callback)/Message——》把Message加入消息队列)给主线程的Handler,Handler从消息队列中取消息,通过handMessage更新UI或者其他处理。
其中,消息队列封装在Looper里,Looper与thread关联,handler与looper关联,即handler与thread建立了关联。handler处理消息用handleCallback/handleMessage。即handler读消息后又处理消息。
示例:
class MYHandler extends Handler
{
public void handleMessage(Message msg)
{
//更新UI
}
}
主线程中:
MyHandler mHandler=new MyHandler();
new Thread()
{
public void run()
{
//耗时操作
mHandler.sendEmptyMessage(123);
};
}.start();
2.Android源码分析
UI线程的消息循环在ActivityThread.main方法中创建,该函数为Android应用程序的入口。
public static void main(String[] args)
{
…………
//创建消息循环looper
Looper.prepareMainLooper();
ActivityThread thread=new ActivityThread ();
thread.attach(false);
if(sMainThreadHanlder==null)
{
//UI线程的handler
sMainThreadHanlder=thread.getHanlder();
}
……
Looper.loop();//执行消息循环
……
}
Handler的默认构造函数:
public Handler()
{
……
mLooper=Looper.myLooper();//获取looper
if(mLooper ==null)
throw new RuntimeException();
mQueue=mLooper.mQueue;//获取消息队列
mCallback=null;
}
Handler的其他函数:
public static Looper myLooper()
{
return sThreadLocal.get();
}
//设置UI线程的Looper
public static void prepareMainLooper()
{
prepare();
setMainLooper(myLooper());
myLooper().mQueue.mQuitAllowed=false;
}
private synchronized static void setMainLooper(Looper looper)
{
mMainLooper=looper;
}
//为当前线程设置looper
public static void prepare()
{
if(s.ThreadLocal.get!=null)
{
throw …………
}
sThreadLocal.set(new Looper());
}
//执行消息循环
public static void loop()
{
Looper me=myLooper();
if(me ==null)
throw……
MessageQueue queue=me.mQueue;//获取消息队列
……
//死循环
while(true)
{
//获取消息
Message msg=queue.next();
if(msg!=null)
{
if(msg.target==null) return;
}
//处理消息
msg.target.dispatchMessage(msg);
msg.reclycl