安卓 手写消息机制

前言

原理性的东西大家都很熟悉了,这里就不老生常谈了,主要是最近一位朋友面试遇到了此要求,希望我能帮他写出来,所以我简单地根据源码撸了大概的样子出来,流程基本有,主要是创建Looper,里面在创建维护着一个MessageQueen,再把Looper存入ThreadLocal,创建Handler,sendMssage的时候把这个Message的Target设置为当前Handler,然后把Message压入MessageQueen,最后开启Looper循环从MessageQueen获取Message然后从Target取出Handler交由其HandlerMessage处理。

MyHandler

public class MyHandler {
private String instance;
public Callback callback;
private MyLooper myLooper;
public interface Callback {
public boolean handleMessage(MyMessage msg);
}
public MyHandler(String instance, Callback callback) {
this.instance = instance;
this.callback = callback;
this.myLooper = MyLooper.myLooper();
;
}
public void sendMyMessage(MyMessage myMessage) {
if (myMessage != null) {
myMessage.setTarget(this);
}
System.out.println("消息进队列:" + instance);
myLooper.queueMessage(myMessage);


}
@Override
public String toString() {
return instance;
}
}

MyLooper

public class MyLooper {
    private MyMessageQueue myMessageQueue;
    static final ThreadLocal<MyLooper> sThreadLocal = new ThreadLocal<MyLooper>();
    private MyLooper() {
    myMessageQueue = MyMessageQueue.getInstance();
    }
    public static void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new MyLooper());
    }
    public static void loop() {
    final MyLooper me = myLooper();
    for (;;) {
    MyMessage msg = me.myMessageQueue.next();
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            if (msg != null) {
            msg.getTarget().callback.handleMessage(msg);
            }
    }
    }
    public static MyLooper myLooper() {
        return sThreadLocal.get();
    }
    public void queueMessage(MyMessage myMessage) {
        try {
        myMessageQueue.produce(myMessage);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


MyMessage

public class MyMessage  {
    private MyHandler target;
    private String what;


    public MyMessage(String what) {
        this.what = what;
    }


    public String getWhat() {
        return what;
    }


    public void setWhat(String what) {
        this.what = what;
    }


    public MyHandler getTarget() {
        return target;
    }


    public void setTarget(MyHandler target) {
        this.target = target;
    }


}



MyMessageQueue

public class MyMessageQueue {


private LinkedBlockingQueue<MyMessage> linkedBlockingQueue = new LinkedBlockingQueue<MyMessage>();


private static MyMessageQueue instance;


private MyMessageQueue() {
}


public static synchronized MyMessageQueue getInstance() {
if (instance == null) {
instance = new MyMessageQueue();
}
return instance;
}


public void produce(MyMessage myMessage) throws InterruptedException {
linkedBlockingQueue.put(myMessage);
}


public MyMessage consume() throws InterruptedException {
return linkedBlockingQueue.take();
}


public MyMessage next() {
MyMessage msg = null;
try {
msg = consume();
} catch (InterruptedException ex) {
System.out.println("MyLooper Interrupted");
}
return msg;
}
}


Test

public class Test {
    public static void main(String[] args) {
    MyLooper.prepare();


        final MyHandler myHandler1 = new MyHandler("firsthandler",new MyHandler.Callback() {
            public boolean handleMessage(MyMessage msg) {
                System.out.println(msg.getTarget().toString()+msg.getWhat());
                return false;
            }
        });
        final MyHandler myHandler2 = new MyHandler("secondhandler", new MyHandler.Callback() {
            public boolean handleMessage(MyMessage msg) {
                System.out.println(msg.getTarget().toString()+msg.getWhat());
                return false;
            }
        });
        new Thread(new Runnable() {
            public void run() {
                MyMessage myMessage = new MyMessage("这是第一个handler的消息");
                myHandler1.sendMyMessage(myMessage);
                MyMessage myMessage1 = new MyMessage("这是第一个handler的消息");
                myHandler1.sendMyMessage(myMessage1);
            }
        }).start();
        new Thread(new Runnable() {
            public void run() {
                MyMessage myMessage = new MyMessage("这是第二个handler的消息");
                myHandler2.sendMyMessage(myMessage);
            }
        }).start();
        
        MyLooper.loop();
    }
}

猜你喜欢

转载自blog.csdn.net/u012874222/article/details/78116708
今日推荐