Android的handler機制理解


1、Handler機制是Android提供的一種異步回調機制,在Ui線程中使用handler需要new一個handler對象,並重寫其中的handleMessage(Message msg)方法,處理如更新UI等操作。
    private Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            //to do
        }
    };

然后在異步線程中調用hanlder.sendMessage(Message msg)告訴UI線程去更新UI等操作。

從原理上來講,使用了Hanlder對象的線程需要綁定一個Looper對象,該對象維護一個消息隊列,Looper對象取出該隊列的消息后交由handler進行處理。所以在使用Handler時,要調用Looper.prepare()方法給當前的線程綁定一個Looper對象。
    
    public static void prepare() {
        prepare(true);
    }

    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));
    }

然后調用loop()建立對消息隊列的循環,在消息隊列中取出消息后交由相應的handler進行處理。由於一個線程中可能有多個handler,為了區分這些不同的hanlder所需要處理的消息,每個Message對象都維護有一個hanlder實例即target,在loop方法中通過調用msg.target.dispatchMessage(msg)進行處理。

每個線程只能綁定一個loop對象,多個handler共享,handler的在構造時從當前的線程中取得loop對象,Looper中的myLooper中返回了sThreadLocal.get()所取得的Looper對象

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;

所以,在使用handler中需要執行以下步驟,首先調用Looper.prepare()方法為當前線程綁定Looper對象,然后才可以實例化一個Handler對象,最后調用loop()方法建立消息循環

 class LooperThread extends Thread {
        public Handler mHandler;
  
        public void run() {
            Looper.prepare();
  
            mHandler = new Handler() {
                public void handleMessage(Message msg) {
                    // process incoming messages here
                }
            };
            Looper.loop();
        }
    }

在很多情況下我們在activity或者其他場合中使用Handler進行異步消息處理,並沒有顯式地聲明綁定一個Looper對象。這是因為主線程它已經綁定了一個Looper對象

    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>";
        Slog.i(TAG, "Main thread of " + name + " is now exiting");
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM