专栏首页Sorrower的专栏Android用5种方式实现自定义计时器, 哪种才是你的菜?

Android用5种方式实现自定义计时器, 哪种才是你的菜?

Chronometer和CountDownTimer计时器 github传送门


效果图

看下效果图, 这是五种不同的方式演示计时器. 当然不看源码是看不出差别的.

效果图


前言

这次的文章不知道能不能帮助大家, 但是对我自己的帮助还是蛮大的, 才知道自己原来用的方法不是最优而且也不是最简. 然后我之前有一篇文章是用官方控件和类实现的, 有兴趣可以看一下Chronometer和CountDownTimer计时器.


Timer + TimerTask + Handler

在TimerTask实例的run方法中用Handler实例发送消息, 用Timer实例启动计时器, 从0ms开始, 间隔1000ms.

case R.id.cv_start1:
    if (mTimer1 == null && mTask1 == null) {
        mTimer1 = new Timer();
        mTask1 = new TimerTask() {
            @Override
            public void run() {
                Message message = mHandler.obtainMessage(1);
                mHandler.sendMessage(message);
            }
        };
        mTimer1.schedule(mTask1, 0, 1000);
    }
    break;

case R.id.cv_stop1:
    if (mTimer1 != null) {
        mTimer1.cancel();
        mTimer1 = null;
    }
    if (mTask1 != null) {
        mTask1.cancel();
        mTask1 = null;
    }
    break;

Timer + TimerTask

比起第一种, 这种更Java, 但是可以少一个Handler实例.

if (mTimer2 == null && mTask2 == null) {
    mTimer2 = new Timer();
    mTask2 = new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mTvTime2.setText(getTime());
                }
            });
        }
    };
    mTimer2.schedule(mTask2, 0, 1000);
}

Handler

这种方法就直接告别Timer和TimerTask了, 通过Handler的发消息延迟sendMessageDelayed以及不同的消息内容(就是what值)解决问题.

case R.id.cv_start3: {
    Message message = mHandler.obtainMessage(2);
    mHandler.sendMessage(message);
}
break;

case R.id.cv_stop3: {
    Message message = mHandler.obtainMessage(3);
    mHandler.sendMessage(message);
}
case 2: {
    mTvTime3.setText(getTime());
    this.removeMessages(2);
    Message message = this.obtainMessage(2);
    this.sendMessageDelayed(message, 1000);
}
break;

case 3:
    this.removeMessages(2);
    break;

Thread + Handler

老朋友Thread + Handler, 原来经常这么写, 现在不了(手动滑稽).

/**
 * 启动线程
 */
private void startThread() {
    if (mThread == null) {
        mThread = new MyThread();
        mThread.start();
    }
}

/**
 * 停止线程
 */
private void stopThread() {
    if (mThread != null) {
        mThread.stop = true;
        mThread = null;
        Message message = mHandler.obtainMessage(5);
        mHandler.sendMessage(message);
    }
}

Handler + Runnable

最后一种我目前最喜欢. 你连what值都无需处理, 直接postDelayed设置时延, 然后交给实现Runnable接口的实例的run方法来做.

case R.id.cv_start5: {
    if (mRunnable == null) {
        mRunnable = new MyRunnable();
        mHandler.postDelayed(mRunnable, 0);
    }
}
break;

case R.id.cv_stop5: {
    mHandler.removeCallbacks(mRunnable);
    mRunnable = null;
}
break;
private class MyRunnable implements Runnable {
    @Override
    public void run() {
        mTvTime5.setText(getTime());
        mHandler.postDelayed(this, 1000);
    }
}

最后

总之一点, 用第三种Handler和第五种Handler + Runnable肯定比其它的消耗少得多, 所以很推荐. 或者你还有更棒的方法可以评论区告诉我下. 喜欢记得点赞, 暗中关注我也是可以的哦~


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 动画必须有(二):悬浮菜单了解一下!

    sean_yang
  • 内核必须懂(七): Linux四级页表(x64)

    sean_yang
  • Android RecyclerView从入门到玩坏

    sean_yang
  • 四两拨千斤,如何做到自然语言预训练加速十倍

    【新智元导读】随着自然语言处理中的预训练成为研究领域的热点,预训练的成本与计算代价也成为了大家在研究过程中必须考虑的现实问题。本文将会介绍多种在训练模型过程中提...

    新智元
  • 动态控制SAP CRM附件的可编辑性

    In production code it is ususally necessary to also have authorization control o...

    Jerry Wang
  • ReentrantLock会!ReentrantReadWriteLock呢?不懂快戳进来看看

    我们都知道在Java多线程中,可以使用synchronized关键字来实现线程之间同

    良月柒
  • 企业如何做好密码管理?

    IT 运维小叉为公司新人小A开通了 10 多个应用系统账户,企业微信、绩效系统、CRM 系统、公司内网云盘等等,“健忘症患者“小A为了方便记忆,将各个系统密码全...

    玉符IDaaS
  • 一些帮助你提升效(bi)率(ge)的干货!

    关注我的你,真特别! ? 你的收藏夹需要精心维护 我们程序员,往往需要通过浏览器查阅大量的资料,当然,查阅完之后,顺手点个星星收藏一下,以便下次继续观看,或者先...

    小之丶
  • AT&T在美国12城上线5G网络,而我们关心的是月租多少?

    12月19日消息,美国移动通信运营商AT&T宣布,其5G网络现已在美国12个城市上线,Nighthawk 5G热点将于本周五上市。

    SDNLAB
  • AT&T的百年沉浮

    1876年,亚历山大·贝尔在美国成功申请了电话的专利,成为举世闻名的“电话之父”。

    鲜枣课堂

扫码关注云+社区

领取腾讯云代金券