HandlerThread 소스 읽기

6815 단어
Handler Thread는 한눈에 보면 이것이 Handler 메커니즘을 겨냥한 Thread임을 알 수 있다.코드가 비교적 짧기 때문에 절차가 비교적 적다.일단 원본 다 꺼내.
/**
 * 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 {
    int mPriority;
    int mTid = -1;
    Looper mLooper;

    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 
     * {@link android.os.Process} and not from java.lang.Thread.
     */
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }
    
    /**
     * Call back method that can be explicitly overridden if needed to execute some
     * setup before Looper loops.
     */
    protected void onLooperPrepared() {
    }

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        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();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

    /**
     * Quits the handler thread's looper.
     * 

* Causes the handler thread's looper to terminate without processing any * more messages in the message queue. *

* Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. *

* Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. *

* * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. * * @see #quitSafely */ public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; } /** * Quits the handler thread's looper safely. *

* Causes the handler thread's looper to terminate as soon as all remaining messages * in the message queue that are already due to be delivered have been handled. * Pending delayed messages with due times in the future will not be delivered. *

* Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. *

* If the thread has not been started or has finished (that is if * {@link #getLooper} returns null), then false is returned. * Otherwise the looper is asked to quit and true is returned. *

* * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. */ public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } /** * Returns the identifier of this thread. See Process.myTid(). */ public int getThreadId() { return mTid; } }

원본, 클래스 설명을 순서대로 읽습니다.
새로운 루틴을 만드는 데 편리한 Looper가 있습니다. 이 Looper는Handler 클래스를 만드는 데 사용됩니다.그러나handler를 만들기 전에handlerThread의 start 방법을 사용해야 합니다.
구성원 변수
    int mPriority;
    int mTid = -1;
    Looper mLooper;

하나는 스레드 우선 순위, 하나는 Id, 마지막은 Looper입니다.핸들러가 핸들러와 Thread에 대한 봉인된 이상 핸들러 소식을 끊임없이 처리해야 할 것이다.우리는 Looper가 끊임없이 메시지 대기열에서Handler에게 메시지를 꺼낸다는 것을 안다.주 스레드에서Handler를 사용할 때 Looper에 대해 어떠한 조작도 할 필요가 없습니다. 사실은 주 스레드가 이러한 조작을 숨겼습니다.HandlerTHread처럼 이러한 작업을 숨깁니다.
구조 함수를 보도록 하겠습니다.
    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 
     * {@link android.os.Process} and not from java.lang.Thread.
     */
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }

특별히 라인을 만들고 라인의 우선순위를 설정하는 것만은 아니다.
라인이니까 런 방법이 관건이야.
    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

Looper 대상을 만들고 Looper의 메시지 메커니즘을 열었습니다. (MessageQueue에 메시지가 있는지 끊임없이 감청하고Handler에 처리합니다.)Looper는 사순환이기 때문에, 이 런 방법도 사순환이다.HandlerThread를 끝내려면 Looper를 종료해야 합니다. 여기는HandlerThread가 두 가지 방법으로 봉인되어 있습니다.
   public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
   }

   public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
   }

그리고 없어졌어요?확실히 그렇습니다. Handler가 현재HandlerThread에서 실행되고 있는지 물어볼 수도 있습니다.일반적으로Thread에서 실행될 동작은run에서 호출되어야 합니다. 여기서는Handler의handle Message 방법을 보지 못했습니다.OK, 사실Handler 메커니즘을 이해하는 사람들은 Looper의loop 방법은 끊임없이 정보를 꺼낸 다음에Handler의dispatchMassage 방법을 사용했다. 이 방법은Handler 정보를 처리하는 것이다.HandlerThread의run 방법에서 Looper가 호출되었기 때문입니다.loop () 방법입니다. 따라서handler의handleMassage 방법을handlerThread에서 실행합니다.

좋은 웹페이지 즐겨찾기