Android Handler计时的优化

Android Handler计时的优化

    handler计时方式,我们通常是在主线程中通过handler.postDealyed(……,200),并在onHandleMessage中继续post消息,这样就实现了每隔200ms进行一次消息循环。

    这种方式是不准确的,有误差,误差的原因在于在你收到消息,到你重新发出handler.postDealyed的时间,并不是瞬间完成的,这里面有很多逻辑处理的时间,即使没有逻辑处理的时间,handler本身也是耗损性能的,所以消息并不可能按照理想的200ms延迟来进行发送。

    所以,我们每次在post的时候,都需要对计时进行下补偿,查看TextClock源码,它是这样处理的:

private final Runnable mTicker = new Runnable() {
    public void run() {
        onTimeChanged();

        long now = SystemClock.uptimeMillis();
        long next = now + (1000 - now % 1000);

        getHandler().postAtTime(mTicker, next);
    }
};

    这里系统使用了postAtTime,这是为什么呢?再看前面两行代码,代个值进去试下,假如now取出来是1200,那么next =1200 + (1000 - 1200 % 1000)也就是next=2000。虽然我们前一次本该在1000触发的事件,被各种逻辑延迟到1200,那么如果用postDelay,这个延迟就被累积了,但如果用这种方式,误差就被补偿了。

    因此,我们可以这样用:

private void startTimeHandler() {
    //误差补偿算法,如now取出来是1200,那么next = 1200 + (1000 - 1200 % 1000)也就是next= 2000。
    long now = SystemClock.uptimeMillis(); //
    long next = now + (1000 - now % 1000);
    mTimeHander.sendEmptyMessageAtTime(0, next);
}
private static class TimeHander extends Handler {

    WeakReference<RecordService> rsWeakReference;

    TimeHander(RecordService rs) {
        this.rsWeakReference = new WeakReference(rs);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        RecordService rs = rsWeakReference.get();
        rs.startTimeHandler();
    }
}

说明:

SystemClock.uptimeMillis() // 从开机到现在的毫秒数(手机睡眠的时间不包括在内);
System.currentTimeMillis() // 从1970年1月1日 UTC到现在的毫秒数;
System.currentTimeMillis() 获取的时间,是可以通过System.setCurrentTimeMillis修改的,那么,在某些情况下,一但被修改,时间间隔就不准了。

参考链接:https://www.jianshu.com/p/56f37988428b

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值