源碼簡讀之Handler

Handler使用

private static Handler mHandler;
mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
    }
};
new Thread( new Runnable() {
    @Override
    public void run() {
        Message message = Message.obtain();
        message.what = 0;
        message.obj = "執行操作";
        mHandler.sendMessage(message);
    }
}).start();

// 爲避免內存泄漏,可以在onDestroy()中調用該方法
handler.removeCallbacksAndMessages(null);

Handler實現原理

在創建Handler時,需要綁定一個Looper對象。但是我們平常沒有設置過是因爲UIThread已經調用了prepareMainLooper();
在初始化構造函數裏,會先檢查是否爲static的類,否則會發出泄漏的警告。然後再創建一個Looper對象,mLooper = Looper.myLooper();

Looper類

使用ThreadLocal類來維護一個線程私有的Looper類。
在構造函數中,創建了一個MessageQueue消息隊列。
在Looper.class中,維護了一個sMainLooper是主線程的Looper對象。
調用loop()方法,執行一個死循環,一直排查MessageQueue中是否有消息,如果有,發送給Handler。

在子線程中操作主線程,可以通過 Looper.prepare()//要執行的代碼// Looper.loop() 實現

在ActivityThread-main方法中,已經調用了Looper.prepareMainLooper()

private static Looper sMainLooper;  // guarded by Looper.class
/**
 * 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.  See also: {@link #prepare()}
 */
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;
    }
}

private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}

WeakHandler

在Android中,我們會經常使用到Handler,由於Handler會持有Activity等對象,導致Activity無法正常釋放。解決這個問題比較好的一種方式就是使用WeakHandler。WeakHandler的實現如下代碼所示

public class WeakHandler extends Handler {

    public static interface IHandler {
        public void handlerMessage(Message msg);
    }

    private final WeakReference<IHandler> mWeakHandler;

    public WeakHandler(IHandler handler) {
        this.mWeakHandler = new WeakReference<IHandler>(handler);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        IHandler handler = mWeakHandler.get();
        if (null == handler)
            return;
        handler.handlerMessage(msg);
    }
}

WeakHandler用法

public class TestActivity extends BaseActivity implements WeakHandler.IHandler {
    private final WeakHandler mHandler = new WeakHandler(this);
    public void onCreate(Bundle savedInstanceBundle) {
        super.onCreate(savedInstanceBundle);
        TestThread thread = new TestThread(mHandler);
        thread.start();
    }
    public void handleMessage(Message msg) {
          // do something
    }
}

public class TestThread extends Thread {
    private final WeakHandler mHandler;
    public TestThread(WeakHandler handler) {
        mHander = handler;
    }
    publicvoid run() {
        mHandler.sendMessage(0);
    }
}

WeakHandler的其他作用

  1. 可以使用來做UI線程的延遲,代替View.post方法
  2. WeakHandler可以當計時器或者用在需要循環刷新的地方
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章