美文网首页
10分钟看懂android中Looper的消息循环机制以及Han

10分钟看懂android中Looper的消息循环机制以及Han

作者: 嘿嘿嘿_y | 来源:发表于2018-03-20 17:04 被阅读0次

    android的Looper和Handler机制。 最好的资料是第一手资料就是源码,可以结合别人的概念性的讲解来看。

    以下代码是中 android源码里简化出来的模型,已经简化的不能再简化了但保留了所有精华,这比那些分析源码的更加接地气,因为能直接跑起来了,这样就很容易的弄懂它的意思了。

    把下面四个类随便贴到项目里 执行main方法。

    Looper :

     public class Looper {
     static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    
    final BlockingQueue<Message> mQueue;
    final Thread mThread;
    
    public static void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }
    
    private Looper() {
        mQueue = new LinkedBlockingQueue<>();
        mThread = Thread.currentThread();
    }
    
    static Looper myLooper() {
        return sThreadLocal.get();
    }
    
    public static void loop() {
        final Looper me = myLooper();
    
        for (; ; ) {
            Message message = null;
            try {
                message = (Message) me.mQueue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (message != null)
                message.callback.handleMessage(message.msg);
        }
    }
    }
    

    Handler:

    public class MyHandler {
    private final Looper mLooper;
    final BlockingQueue<Message> mQueue;
    private final Callback mCallback;
    
    public MyHandler(Callback callback) {
        mLooper = Looper.myLooper();
        mQueue = mLooper.mQueue;  // 在当前线程创建handler对象。然后创建了一个looper对象,是个当前线程的副本,内部封装了一个消息队列。当前线程通过执行loop方法来循环遍历该队列。
        mCallback = callback;
    }
    
    public void sendMessage(int msg) {   // 在其他线程调用,把消息添加到该handler持有的消息队列中,该消息队列被创建该handler的线程所循环遍历。
        Message message = new Message(msg);
        message.callback = mCallback;
        Queue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        mQueue.offer(message);
    }
    
    public interface Callback {
        public boolean handleMessage(int msg);
    }
    }
    

    Message:

    public class Message {
    int msg;
    public MyHandler.Callback callback;
    
    public Message(int msg) {
        this.msg = msg;
    }
    }
    

    测试类:

    public class MainTest {
    public static void main(String args[]) {
        Looper.prepare();  // 创建Looper对象。并将该对象存储在当前线程副本。
    
        final MyHandler handler = new MyHandler(new MyHandler.Callback() { // 主线程中的消息处理器。
            @Override
            public boolean handleMessage(int msg) {
                System.out.println(Thread.currentThread().getId() + " 主线程收到了消息 msg= " + msg);
                return false;
            }
        });
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (; ; ) {
                    handler.sendMessage(1);  // 每隔2秒向主线程发送消息。
    
                    System.out.println(Thread.currentThread().getId() + " sendMessage ");
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    
        Looper.loop();  // 执行循环遍历消息队列。
    }
    }

    相关文章

      网友评论

          本文标题:10分钟看懂android中Looper的消息循环机制以及Han

          本文链接:https://www.haomeiwen.com/subject/prpbqftx.html