Handler和它的小姐妹HandlerThread

来源:互联网 发布:js history 编辑:程序博客网 时间:2024/04/29 08:09

Android应用程序也是消息驱动的
Activity是一个UI线程,运行于主线程中,Android系统在启动的时候会为Activity创建一个消息队列和消息循环(Looper),详细实现请参考ActivityThread.java文件。

1.3.1消息的生成

   Message msg =mHandler.obtainMessage();   msg.what = what;   msg.sendToTarget();

1.3.2消息的发送

   MessageQueue queue= mQueue;    if (queue != null){        msg.target =this;        sent =queue.enqueueMessage(msg, uptimeMillis);    }  在Handler.java的sendMessageAtTime(Messagemsg, long uptimeMillis)方法中,我们看到,它找到它所引用的MessageQueue,然后将Message的target设定成自己(目的是为了在处理消息环节,Message能找到正确的Handler),再将这个Message纳入到消息队列中。

1.3.3消息的抽取

    Looper me =myLooper();    MessageQueue queue= me.mQueue;    while (true) {        Message msg =queue.next(); // might block        if (msg !=null) {            if(msg.target == null) {                // Notarget is a magic identifier for the quit message.               return;            }            msg.target.dispatchMessage(msg);           msg.recycle();        }    } 

1.3.4消息的处理

    if (msg.callback!= null) {       handleCallback(msg);    } else {        if (mCallback!= null) {            if(mCallback.handleMessage(msg)) {                return;            }        }       handleMessage(msg);    } 

private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException(“Only one Looper may be created per thread”);
}
sThreadLocal.set(new Looper(quitAllowed));

public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException(“The main Looper has already been prepared.”);
}
sMainLooper = myLooper();
}
}

/** Returns the application’s main looper, which lives in the main thread of the application.
*/
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}

Loop.prepare()都会提供一个当前Looper以及相应的MessageQueue
主线程在Activity创建之初就已经提供了Looper,直接使用就好(prepareMainLooper(), getMainLooper()google已经帮我们封装在底层,贴心奶奶呀)

Handler的处理过程运行在创建Handler的线程里
一个Looper对应一个MessageQueue,一个线程对应一个Looper,一个Looper可以对应多个Handler

handler与创建它的线程相关联,而且也只与创建它的线程相关联。handler运行在创建它的线程中,所以,如果在handler中进行耗时的操作,会阻塞创建它的线程。

以上内容原博:http://blog.csdn.net/h3c4lenovo/article/details 特此说明

2.HandlerThread
//生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功
//能,这个类由Android应用程序框架提供
mHandlerThread = new HandlerThread(“handler_thread”);

   mHandlerThread.start();   //即这个Handler是运行在mHandlerThread这个线程中   mMyHandler = new MyHandler(mHandlerThread.getLooper());   mMyHandler.sendEmptyMessage(1);

//在使用HandlerThread的getLooper()方法之前,必须先调用该类的start();

原因:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}

理解:看源码还是会清晰很多,有点表达不出来
总结:HandlerThread就是一个提供了Looper的 Thread
使用HandlerThread的looper创建相应的handler可以进行消息传递
private static final HandlerThread sWorkerThread = new HandlerThread(TAG);
static {
sWorkerThread.start();
}
private static final Handler sWorker = new Handler(sWorkerThread.getLooper());
private void runOnWorkerThread(Runnable r) {
if (sWorkerThread.getThreadId() == Process.myTid()) {
r.run();
} else {
// If we are not on the worker thread, then post to the worker handler
sWorker.post(r);
}
}

PS:
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

这里就是上半部分Handler中我们没有讲述的callBack为空的情况,callback就是runnable
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
。。。。。。
}
}

private static void handleCallback(Message message) {
message.callback.run();
}

0 0