Handler ,Looper,MessageQueue

Looper主要完成Handler与MessageQueue进行交互,主要用于线程间通信;

线程间通信:大家都知道子线程不能直接操作主线程(UI线程),也都知道ui线程已经为我们创建了looper;

//Thread1 
new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                handler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        System.out.println("这个消息是从-->>" + msg.obj
                                + "过来的,在" + "btn的子线程当中" + "中执行的");
                        Toast.makeText(MainActivity.this, ":" + msg.obj, Toast.LENGTH_LONG).show();
                    }
                };
                Looper.loop();
            }
        }).start();
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Thread2
                new Thread(new Runnable() {
                    @Override
                    public void run() {
//                        Looper.prepare();
                        Message message = Message.obtain();
                        message.obj = getClipBoard();
                        System.out.println("这个消息是从----->>" + message.obj
                                + "过来的,在" + "btn的子线程当中" + "中执行的");

                       // Toast.makeText(MainActivity.this, ":--" + message.obj, Toast.LENGTH_LONG).show();

                        handler.sendMessage(message);
//                        Looper.loop();
                    }
                }).start();
            }
        });

Thread1中如果不加入Looper.prepare() 则会报错:不能在没有调用Looper.prepare()的子线程中创建handler;

Looper.prepare() 实际是创建looper;

Looper.loop()中实现了一个死循环不断的从messageQueue中取出Message,转交给message.target即Handler进行处理:

Looper 源码:

private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
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));
    }

public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
       }
        final MessageQueue queue = me.mQueue;

        ...
        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
        ...
            try {
                msg.target.dispatchMessage(msg);
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
        ...

            msg.recycleUnchecked();
        }
    }

Looper:成员变量 :mQueue =new MessageQueue,mThread  中通过ThreadLocal((线程局部变量)将私有线程和该线程存放的副本对象作为一个映射,各个线程间变量互不干扰)为了确保每个线程只对应一个Looper

Handler成员变量:mLooper=Looper.myLooper()、mQueue = mLooper.mQueue、mCallback

通过mLooper and mQueue将looper与Handler关联起来

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
690        MessageQueue queue = mQueue;
691        if (queue == null) {
692            RuntimeException e = new RuntimeException(
693                    this + " sendMessageAtTime() called with no mQueue");
694            Log.w("Looper", e.getMessage(), e);
695            return false;
696        }
697        return enqueueMessage(queue, msg, uptimeMillis);
698    }

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
741        msg.target = this;//****
742        if (mAsynchronous) {
743            msg.setAsynchronous(true);
744        }
745        return queue.enqueueMessage(msg, uptimeMillis);
746    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值