手把手 教你 写 Handler 源码

1.貼 相关 优秀作者的链接:

Android Handler:手把手带你深入分析 Handler机制源码

2.Android Handler:图文解析 Handler通信机制 的工作原理

3.Android:这是一份Handler消息传递机制 的使用教程

 

好了,以下內容,來自網易 云课堂 相关 知识,如有侵权,联系我..

Handler

package com.example.leger.myhandlerlib;



public class Handler {


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

    public  MessageQueue mQueue;

    /**
     * 发送消息
     * @param msg
     */
    public void sendMessage(Message msg){
        msg.target = this;
        mQueue.enqueueMessage(msg);
    }

    public void handleMessage(Message msg){

    }

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

}

 

 

Looper

 

package com.example.leger.myhandlerlib;


public class Looper {

    public MessageQueue mQueue;

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

    static ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>();

    /**
     * 初始化prepare   ,将其保存到sThreadLocal 中
     */
    public static void prepare(){
        prepare(true);
    }

    private static void prepare(boolean quitAllowed){
        if(sThreadLocal.get() != null){
            throw new RuntimeException("only one looper may be create per thread");
        }
        sThreadLocal.set(new Looper());
    }

    public static Looper myLooper(){
        return sThreadLocal.get();//保证返回的对象 是当前线程的Looper
    }

    public static void loop(){
        Looper me = myLooper();

        if(me == null){
            throw new RuntimeException("当前线程没有Looper 对象");
        }

        MessageQueue queue = me.mQueue;

        //拿到了消息队列后
        for (;;){
            Message msg = queue.next();

            if(msg != null){
                msg.target.dispatchMessage(msg);
            }
        }
    }
}

 

 

Message

package com.example.leger.myhandlerlib;

public class Message {
    Handler target;
    Object   obj;

    public  int what;
    public Message(){

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

 

MessageQueue

 

package com.example.leger.myhandlerlib;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MessageQueue {

    /**
     * 存 message ,在这里用 数组
     *
     */
    private Message[] items;

    /**
     *
     */
    private int putIndex;
    private int takeIndex;


    private final  int QueueMaxSize = 10;

    private int count;
    //锁
    private Lock lock;

    /**
     * 条件变量
     */
    private Condition notEmpty;
    private Condition notFull;



    public MessageQueue(){
        items = new Message[QueueMaxSize];
        lock = new ReentrantLock();//可重入
        notEmpty = lock.newCondition();
        notFull = lock.newCondition();
    }

    /**
     * 入队
     * @param msg
     */
    public void enqueueMessage(Message msg){

        try {
            lock.lock();
            while(count == QueueMaxSize){
                notFull.await();
            }

            items[putIndex] = msg;

            putIndex = (++putIndex == items.length)?0:putIndex;

            count++;

            //已经生产,可以消费了
            notEmpty.signalAll();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }

    /**
     * 取出队列中的消息
     * @return
     */
    public Message next(){

        Message msg = null;

        try {
            lock.lock();
            //没有了,  等待
            while(count == 0){
                notEmpty.await();
            }
            msg = items[takeIndex];

            takeIndex = (++takeIndex == items.length)?0:takeIndex;

            count--;
            //已经消费,可以继续生产
            notFull.signalAll();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

        return msg;
    }

}

 

 

 

最后 是测试类

package com.example.leger.myhandlerlib;


import java.util.UUID;

public class HandlerTest {
    private static final String TAG = "HandlerTest";

    public static void main(String args[]){
        System.out.println("hello world");

        Looper.prepare();

        final Handler mHandler  = new Handler(){
            @Override
            public void handleMessage(Message msg){
                super.handleMessage(msg);
                System.out.println("main =" + Thread.currentThread().getName() + " , msg = "+ msg.toString());
            }
        };

        for (int i = 0;i < 5;i++)
        {
            new Thread(){
                @Override
                public void  run()
                {
                    while (true)
                    {
                        Message msg = new Message();
                        synchronized (UUID.class){
                            msg.obj = UUID.randomUUID().toString();
                        }

                        System.out.println("send =" + Thread.currentThread().getName() + " , msg = "+ msg.toString());
                        mHandler.sendMessage(msg);//工作线程发送这个消息是怎么样到达UI线程的?  Handler内部 持有一个MessageQueue,把消息入队,Message内部持有 当前的Handler,也就是说,在sendMessage内部 就已经确定是谁 发来的消息了, 而Handler 内部的 dispathMessage 实际上调用的还是handleMessage


                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            }.start();
        }

        Looper.loop();//内部是个 for 循环,不断取队列 数据,然后把 消息 分发 相应的Handler ,(调用Handler 的dispathMessage 函数),达到了消息循环,并且把 消息对应于 个Handler 的原理.


    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Teleger

你的支持是我前进的方向

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值