<深入理解Android内核设计思想>读书笔记:Looper,Handler,Runnable,MessageQueue,ActivityThread

本文详细解析了Android中的Looper机制,包括Looper、Handler与MessageQueue的关系,它们如何协同工作以实现线程间的通信。同时介绍了ActivityThread中的Looper使用方式及Looper.loop()方法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Looper不断获取MessageQueue中的一个Message,交给Handler处理。加入队列为空,Looper进入休眠。


几者的关系:
每个Thread只对应一个Looper;
每个Looper只对应一个MessageQueue;
每个MessageQueue中有N个Messsage;
每个Message最多指定一个Handler来处理事件。


Handler的功能:
1.处理Message;
        handlerMessage(msg);
        dispatchMessage(msg);
2.将Message压入MessageQueue(为什么要先压入queue中,而不是直接处理,这体现了程序设计的“有序性”);
        post(runnable);
        sendMessage(msg);
post是将runnable转换成message送入messageQueue中。
public final boolean post(Runnable r){  
    return sendMessageDelayed(getPostMessage(r),0);  
}  
private static Message getPostMessage(Runnable r){  
    Message m = Message.obtain();//Android系统维护的全局Message池。避免资源浪费。  
    m.callback = r;  
    return m;  
}  
public boolean sendMessageAtTime(Message msg, long uptimeMillis){  
    MessageQueue queue = mQueue;  
    msg.target = this;  
    return enqueueMessage(queue, msg, uptimeMillis);  
} 

Looper的使用:  
class LooperThread extends Thread{  
    public Handler mHandler;  
    public void run(){  
        Looper.prepare();  
        mHandler = new Handler(){  
            public void handlerMessage(){  
                //TODO  
            }  
        };   
        Looper.loop();  
    }  
}

默认的线程不存在消息循环,所以不用使用Looper。  

 

Looper的创建:

//Looper中的代码  
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();  
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));  
}

可见looper是在这里new的,可是它怎么和thread关联上的呢,看下面的代码:  

//ThreadLocal.java  
public void set(T value) {  
    Thread currentThread = Thread.currentThread();  
    Values values = values(currentThread);  
    if (values == null) {  
        values = initializeValues(currentThread);  
    }  
    values.put(this, value);  
}

这里获取了当前线程,put中做了一系列操作,将当前线程与looper关联了起来。  


MessageQueue的创建:

MessageQueue在创建Looper对象的时候创建。  

//Looper.java  
private Looper() {  
    mQueue = new MessageQueue();  
    mRun = true;  
    mThread = Thread.currentThread();  
}


Handler中获取Looper:

//Handler.java  
public Handler(){  
    mLooper = Looper.myLooper();  
    mQueue = mLooper.mQueue;  
}

//Looper.java  
public static final Looper myLooper() {  
    return (Looper)sThreadLocal.get();  
}
//ThreadLocal.java  
public T get() {  
    Thread currentThread = Thread.currentThread();  
    Values values = values(currentThread);  
    if (values != null) {  
        Object[] table = values.table;  
        int index = hash & values.mask;  
        if (this.reference == table[index]) {  
            return (T) table[index + 1];  
        }  
    } else {  
        values = initializeValues(currentThread);  
    }  
    return (T) values.getAfterMiss(this);  
}

Handler的构造函数中最终调用sTreadLocal.get(),get()可见也是根据当前线程获取当前的looper。  


ActivityThread:

ActivityThread的mani()是进程的入口函数。

//ActivityThread.java  
public static final void main(String[] args) {  
    SamplingProfilerIntegration.start();  
  
    Process.setArgV0("<pre-initialized>");  
  
    Looper.prepareMainLooper();  
  
    ActivityThread thread = new ActivityThread();  
    thread.attach(false);  
  
    Looper.loop();  
  
    if (Process.supportsProcesses()) {  
        throw new RuntimeException("Main thread loop unexpectedly exited");  
    }  
  
    thread.detach();  
    String name = (thread.mInitialApplication != null)  
        ? thread.mInitialApplication.getPackageName()  
        : "<unknown>";  
    Log.i(TAG, "Main thread of " + name + " is now exiting");  
 }
//Looper.java  
public static final void prepareMainLooper() {  
    prepare();  
    setMainLooper(myLooper());  
    if (Process.supportsProcesses()) {  
        myLooper().mQueue.mQuitAllowed = false;  
    }  
}

private synchronized static void setMainLooper(Looper looper) {  
    mMainLooper = looper;  
}

这个主线程和普通线程的区别就是多了个Looper.prepareMainLooper();我感觉它的作用就是为了创建一个mainLooper供其他线程调用。  


Looper.loop(),apk动起来的根本原因:

public static final void loop() {  
    Looper me = myLooper();  
    MessageQueue queue = me.mQueue;  
    while (true) {  
        Message msg = queue.next();  
        if (msg != null) {  
            if (msg.target == null) {  
                return;  
            }  
            if (me.mLogging!= null) me.mLogging.println(  
                    ">>>>> Dispatching to " + msg.target + " "  
                    + msg.callback + ": " + msg.what  
                    );  
            msg.target.dispatchMessage(msg);  
            if (me.mLogging!= null) me.mLogging.println(  
                    "<<<<< Finished to    " + msg.target + " "  
                    + msg.callback);  
            msg.recycle();  
        }  
    }  
}

msg.target为将msg压入queue的handler


Handler处理Message:
//Handler.java  
public void dispatchMessage(Message msg) {  
    if (msg.callback != null) {  
        handleCallback(msg);  
    } else {  
        if (mCallback != null) {  
            if (mCallback.handleMessage(msg)) {  
                return;  
            }  
        }  
        handleMessage(msg);  
    }  
}

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

dispatchMessage()中,判断msg.callback不空的话,就handlerCallback(msg),此时的msg.callback即为上面post时的runnable,所以这里走的是runnable的run()方法。

else中调用的即是重写的handlerMessage()。

View为什么也可以post(runnable):
public boolean post(Runnable action) {  
    Handler handler;  
    if (mAttachInfo != null) {  
        handler = mAttachInfo.mHandler;  
    } else {  
        ViewRoot.getRunQueue().post(action);  
        return true;  
    }  
  
    return handler.post(action);  
}

View中也有post()方法,里面新建了个handler,做了post操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值