WEB开发网
开发学院手机开发Android 开发 Android中HandlerThread类的解释 阅读

Android中HandlerThread类的解释

 2012-08-06 16:07:14 来源:WEB开发网   
核心提示: Android应用中的消息循环由Looper和Handler配合完成,Looper类用于封装消息循环,Android中HandlerThread类的解释,类中有个MessageQueue消息队列;Handler类封装了消息投递和消息处理等功能,系统默认情况下只有主线程(即UI线程)绑定Looper对象,而且使用wai

 Android应用中的消息循环由Looper和Handler配合完成,Looper类用于封装消息循环,类中有个MessageQueue消息队列;Handler类封装了消息投递和消息处理等功能。

系统默认情况下只有主线程(即UI线程)绑定Looper对象,因此在主线程中可以直接创建Handler的实例,但是在子线程中就不能直接new出Handler的实例了,因为子线程默认并没有Looper对象,此时会抛出RuntimeException异常:
浏览下Handler的默认构造函数就一目了然了:
 
 
public Handler() {  
    if (FIND_POTENTIAL_LEAKS) {  
        final Class<? extends Handler> klass = getClass();  
        if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&  
                (klass.getModifiers() & Modifier.STATIC) == 0) {  
            Log.w(TAG, "The following Handler class should be static or leaks might occur: " +  
                klass.getCanonicalName());  
        }  
    }  
  
    mLooper = Looper.myLooper();  
    if (mLooper == null) {  
        throw new RuntimeException(  
            "Can't create handler inside thread that has not called Looper.prepare()");  
    }  
    mQueue = mLooper.mQueue;  
    mCallback = null;  
}  
 
 
 
如果需要在子线程中使用Handler类,首先需要创建Looper类实例,这时可以通过Looper.prepare()和Looper.loop()函数来实现的。阅读Framework层源码发现,Android为我们提供了一个HandlerThread类,该类继承Thread类,并使用上面两个函数创建Looper对象,而且使用wait/notifyAll解决了多线程中子线程1获取子线程2的Looper对象为空的问题。HandlerThread类完整代码如下:
 
/** 
 * Handy class for starting a new thread that has a looper. The looper can then 
 * be used to create handler classes. Note that start() must still be called. 
 */  
public class HandlerThread extends Thread {  
      
    private int mPriority; // 线程优先级  
      
    private int mTid = -1; // 线程ID  
      
    private Looper mLooper; // 我们需要的Looper对象  
  
    public HandlerThread(String name) {  
        super(name);  
        mPriority = Process.THREAD_PRIORITY_DEFAULT;  
    }  
  
    /** 
     * Constructs a HandlerThread. 
     *  
     * @param name 
     * @param priority 
     *            The priority to run the thread at. The value supplied must be 
     *            from [email protected] android.os.Process} and not from java.lang.Thread. 
     */  
    public HandlerThread(String name, int priority) {  
        super(name);  
        mPriority = priority;  
    }  
  
    /** 
     * 在Looper.loop()之前执行动作的回调函数 
     */  
    protected void onLooperPrepared() {  
    }  
  
    public void run() {  
        mTid = Process.myTid();  
        Looper.prepare(); // 创建本线程的Looper对象  
          
        synchronized (this) {  
            mLooper = Looper.myLooper();  
            notifyAll(); //通知所有等待该线程Looper对象的其他子线程,本线程的Looper对象已就绪  
        }  
          
        Process.setThreadPriority(mPriority);  
        onLooperPrepared(); //回调函数  
          
        Looper.loop(); //开始消息队列循环  
        mTid = -1;  
    }  
  
    /** 
     * This method returns the Looper associated with this thread. If this 
     * thread not been started or for any reason is isAlive() returns false, 
     * this method will return null. If this thread has been started, this 
     * method will block until the looper has been initialized. 
     *  
     * @return The looper. 
     */  
    public Looper getLooper() {  
        if (!isAlive()) {  
            return null;  
        }  
  
        // If the thread has been started, wait until the looper has been  
        // created.  
        synchronized (this) {  
            while (isAlive() && mLooper == null) {  
                try {  
                    wait(); //Looper对象未创建好,等待  
                } catch (InterruptedException e) {  
                }  
            }  
        }  
        return mLooper;  
    }  
  
    /** 
     * Ask the currently running looper to quit. If the thread has not been 
     * started or has finished (that is if [email protected] #getLooper} returns null), 
     * then false is returned. Otherwise the looper is asked to quit and true is 
     * returned. 
     */  
    public boolean quit() {  
        Looper looper = getLooper();  
        if (looper != null) {  
            looper.quit();  
            return true;  
        }  
        return false;  
    }  
  
    /** 
     * Returns the identifier of this thread. See Process.myTid(). 
     */  
    public int getThreadId() {  
        return mTid;  
    }  
}  
 

Tags:Android HandlerThread 解释

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接