简单的Handler帮助理解原理

Handler

import android.telecom.Call;

import com.fiannce.bawei.common.LogUtil;

public class ShopHandler {
    public ShopMessageQueue shopMessageQueue;
    public CallBack mCallBack;

    public ShopHandler(){
        ShopLooper shopLooper = ShopLooper.getLooper();
        shopMessageQueue = shopLooper.shopMessageQueue;
    }
    public ShopHandler(CallBack callBack) {
        ShopLooper shopLooper = ShopLooper.getLooper();
        shopMessageQueue = shopLooper.shopMessageQueue;
        mCallBack = callBack;
    }

    public void sendEmptyDelayMessage(int what,int delayMills) {
        ShopMessage shopMessage = new ShopMessage();
        shopMessage.what = what;
        shopMessage.when = System.currentTimeMillis()+delayMills;
        shopMessage.target = this;
        shopMessageQueue.enqueueMessage(shopMessage);
    }

    public void sendEmptyMessage(int what) {
        sendEmptyDelayMessage(what,0);
    }

    public void post(Runnable runnable) {
        ShopMessage shopMessage = new ShopMessage();
        shopMessage.callBack = runnable;
        shopMessage.target = this;
        shopMessageQueue.enqueueMessage(shopMessage);
    }

    public void dispatchMessage(ShopMessage shopMessage) {
        if (shopMessage.callBack!=null) {
            shopMessage.callBack.run();
            return;
        } else {
            if (mCallBack!=null) {
                if (mCallBack.handleMessage(shopMessage)) {
                    return;
                }
            }
            handleMessage(shopMessage);
        }
    }

    public void handleMessage(ShopMessage shopMessage) {
        LogUtil.d("what = " + shopMessage.what);
    }

    public interface CallBack {
        boolean handleMessage(ShopMessage shopMessage);
    }
}

Looper

public class ShopLooper {
    private static ThreadLocal<ShopLooper> shopLooperThreadLocal = new ThreadLocal<>();
    public ShopMessageQueue shopMessageQueue;

    public static ShopLooper getLooper() {
        return shopLooperThreadLocal.get();
    }

    public ShopLooper() {
        shopMessageQueue = new ShopMessageQueue();
    }

    public static void prepare() {
        ShopLooper shopLooper = new ShopLooper();
        shopLooperThreadLocal.set(shopLooper);
    }

    public static void loop() {
        for(;;) {
            ShopLooper shopLooper = shopLooperThreadLocal.get();
            ShopMessage shopMessage = shopLooper.shopMessageQueue.next();
            shopMessage.target.dispatchMessage(shopMessage);
        }
    }
}

Message

public class ShopMessage {
    public ShopHandler target;
    public Runnable callBack;
    public long when;

    public int what;
}

MessageQueue


import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class ShopMessageQueue {
    List<ShopMessage> shopMessageList = new ArrayList<>();
    private Timer timer = new Timer();

    public synchronized ShopMessage next() {
        for(;;) {

            if (shopMessageList.size() > 0) {
                ShopMessage shopMessage = shopMessageList.get(0);
                long now = System.currentTimeMillis();//当前时间
                long timeOut = shopMessage.when-now;
                if (timeOut>0) {//如果大于0代表着该条消息还没有到执行时间,需要启动超时定时器,然后睡眠等待定时器唤醒
                     startTimerTask(timeOut);
                    try {
                        wait();
                        continue;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    shopMessageList.remove(shopMessage);
                    return shopMessage;
                }
            } else {
                try {
                    wait();
                    continue;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private synchronized void notifyLooper() {
        //当定时器启动后,需要唤醒looper
        notifyAll();
    }


    private void startTimerTask(long timeOut) {
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                notifyLooper();
            }
        },timeOut);
    }

    //向队列中插入一条消息
    public synchronized void enqueueMessage(ShopMessage shopMessage) {
        int i = 0;
        if (shopMessageList.size() == 0) {
            shopMessageList.add(shopMessage);
            notifyAll();
            return;
        }
        //按照延迟时间的大小将消息在消息队里里排序,延迟小的放到队列的前面。如果两个消息的延迟时间一样,会把消息按照发送时间顺序进行摆放,发送
        //时间早的,放在前面
        for(; i < shopMessageList.size();i++) {
            if (shopMessage.when>=shopMessageList.get(i).when) {
                continue;
            } else {
                shopMessageList.add(i,shopMessage);//如果新消息小于当前队列的该条消息时,则把新消息放到遍历到的队列消息的前面
                break;
            }
        }
        if (i == shopMessageList.size()) {//遍历完后仍然没有找到延迟时间大于新消息的延迟时间的,将该新消息存放到队列的尾部
            shopMessageList.add(shopMessage);
        }

        notifyAll();//新消息插入后,需要唤醒一次looper
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值