当前位置:操作系统 > 安卓/Android >>

Android Looper和Handler分析

 第一次接触android应用程序(这里指的是JAVA层的UI程序,也难怪了,Google放出的API就只支持JAVA应用程序了),很难搞明白内部是如何实现的。但是,从原理上分析,应该是有一个消息循环,一个消息队列,然后主线程不断得从消息队列中取得消息并处理之。
然而,google封装得太厉害了,所以一时半会还是搞不清楚到底是怎么做的。本文将分析android内的looper,这个是用来封装消息循环和消息队列的一个类,handler其实可以看做是一个工具类,用来向消息队列中插入消息的。好比是Windows API的SendMessage中的HANDLE,这个handle是窗口句柄。
//Looper类分析  
//没找到合适的分析代码的办法,只能这么来了。每个重要行的上面都会加上注释  
//功能方面的代码会在代码前加上一段分析  
public class Looper { 
   //static变量,判断是否打印调试信息。  
    private static final boolean DEBUG = false; 
    private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 
 
    // sThreadLocal.get() will return null unless you've called prepare().  
//线程本地存储功能的封装,TLS,thread local storage,什么意思呢?因为存储要么在栈上,例如函数内定义的内部变量。要么在堆上,例如new或者malloc出来的东西  
//但是现在的系统比如Linux和windows都提供了线程本地存储空间,也就是这个存储空间是和线程相关的,一个线程内有一个内部存储空间,这样的话我把线程相关的东西就存储到  
//这个线程的TLS中,就不用放在堆上而进行同步操作了。  
    private static final ThreadLocal sThreadLocal = new ThreadLocal(); 
//消息队列,MessageQueue,看名字就知道是个queue..  
    final MessageQueue mQueue; 
    volatile boolean mRun; 
//和本looper相关的那个线程,初始化为null  
    Thread mThread; 
    private Printer mLogging = null; 
//static变量,代表一个UI Process(也可能是service吧,这里默认就是UI)的主线程  
    private static Looper mMainLooper = null; 
     
     /** Initialize the current thread as a looper.
      * This gives you a chance to create handlers that then reference
      * this looper, before actually starting the loop. Be sure to call
      * {@link #loop()} after calling this method, and end it by calling
      * {@link #quit()}.
      */ 
//往TLS中设上这个Looper对象的,如果这个线程已经设过了looper的话就会报错  
//这说明,一个线程只能设一个looper  
    public static final void prepare() { 
        if (sThreadLocal.get() != null) { 
            throw new RuntimeException("Only one Looper may be created per thread"); 
        } 
        sThreadLocal.set(new Looper()); 
    } 
     
    /** Initialize the current thread as a looper, marking it as an application's main 
     *  looper. The main looper for your application is created by the Android environment,
     *  so you should never need to call this function yourself.
     * {@link #prepare()}
     */ 
 //由framework设置的UI程序的主消息循环,注意,这个主消息循环是不会主动退出的  
//      
    public static final void prepareMainLooper() { 
        prepare(); 
        setMainLooper(myLooper()); 
//判断主消息循环是否能退出....  
//通过quit函数向looper发出退出申请  
        if (Process.supportsProcesses()) { 
            myLooper().mQueue.mQuitAllowed = false; 
        } 
    } 
 
    private synchronized static void setMainLooper(Looper looper) { 
        mMainLooper = looper; 
    } 
     
    /** Returns the application's main looper, which lives in the main thread of the application.
     */ 
    public synchronized static final Looper getMainLooper() { 
        return mMainLooper; 
    } 
 
    /**
     *  Run the message queue in this thread. Be sure to call
     * {@link #quit()} to end the loop.
     */ 
//消息循环,整个程序就在这里while了。  
//这个是static函数喔!  
    public static final void loop() { 
        Looper me = myLooper();//从该线程中取出对应的looper对象  
        MessageQueue queue = me.mQueue;//取消息队列对象...  
        while (true) { 
            Message msg = queue.next(); // might block取消息队列中的一个待处理消息..  
            //if (!me.mRun) {//是否需要退出?mRun是个volatile变量,跨线程同步的,应该是有地方设置它。  
            //    break;  
            //}  
            if (msg != null) { 
                if (msg.target == null) { 
                    // No target is a magic identifier for the quit message.  
                    return; 
                } 
                if (me.mLogging!= null) me.mLogging.println( 
                        ">>>>> Dispatching to " + msg.target + " " 
                        + msg.callback + ": " + msg.what 
                        ); 
                msg.target.dispatchMessage(ms

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,