手寫handler原理實現

基於上篇文章研究了handler的源碼(handler核心原理),自己想手動寫下handler實現原理代碼,項目結構如下:項目目錄結構,自己寫了個單元測試來模擬ActivityThread的啓動,下面是ActivityThread中的main測試方法;

  @Test
    public void main(){
        //創建looper
        Looper.prepare();

        //handler處理消息
        final Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
              System.out.println( msg.obj.toString());
            }
        };

        //子線程發送消息給messagequeue
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message msg = new Message();
                msg.obj = "handlerlocal";
                handler.sendMessage(msg);
            }
        }).start();

        //輪訓,取出消息給handler處理
        Looper.loop();
    }

下面分別是上面幾個類的代碼:

public class Handler {


    public static MessageQueue mQueue;

    public Handler() {
        Looper looper = Looper.myLooper();
        mQueue = looper.mQueue;
    }

    //將message 消息存放到messagequeue中
    public void sendMessage(Message msg) {
        enqueueMessage(msg,mQueue);
    }

    private void enqueueMessage(Message msg, MessageQueue mQueue) {
        msg.target = this; //把handler賦值給了message.target,後面(loop())dispatchMessage就是用的這個handler對象
        mQueue.enqueueMessage(msg);
    }

    public void dispatchMessage(Message msg) {
        handleMessage(msg);
    }
    public void handleMessage(Message msg){

    }
}
public class Looper {

    private static ThreadLocal<Looper> threadLocal = new ThreadLocal<>();

    public static MessageQueue mQueue;
    private Looper(){
        mQueue = new MessageQueue();
    }

    public static void prepare() {
        if (threadLocal.get() != null) {
            new RuntimeException("not init looper agin"); //這樣設計爲了保證looper的唯一性
        }

        threadLocal.set(new Looper()); //綁定當前線程(主線程)和looper
    }


    public static void loop() {
        while (true){ //死循環從阻塞隊列中取出message交給handler處理
            Message msg = mQueue.next();
            msg.target.dispatchMessage(msg);
        }
    }

    public static Looper myLooper() {
        return threadLocal.get();//handler中會調用這個方法取出messagequee對象,把message存放到messagequeue中
    }
}

public class Message {


    public Handler target;
    public Object obj;

    @Override
    public String toString() {
        return obj.toString();
    }
}

public class MessageQueue {


    BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<>(50);
    public void enqueueMessage(Message msg) {

        try {
            blockingQueue.put(msg);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public Message next() {
        try {
            Message msg = blockingQueue.take();
            return msg;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章