Handler vs Timer

在我们Android开发过程中,经常需要执行一些短周期的定时任务,这时候有两个选择Timer或者Handler。然而个人认为: Handler 在多个方面比Timer更为优秀,更推荐使用。

一.易用性

可重复执行 Handler可以重复执行某个任务。 Timer若在某个任务执行/取消之后,再次执行则会抛出一个IllegalStateException异常。为了避免这个异常,需要重新创建一个Timer对象。

周期可调整

若想要执行一个越来越快的定时任务,Handler可以做到,而Timer则消耗较大。 Handler

  • private Handler handler = new Handler();
    int mDelayTime = 1000;
    private Runnable runnable = new Runnable() {
    public void run() {
    update();
    if (mDelayTime > 0) {
    handler.postDelayed(this,mDelayTime);
    mDelayTime -= 100;
    }
    }
    };
    handler.postDelayed(runnable,1000);

如以上例子,就可以实现对周期的动态调整。 Timer的scheduleAtFixedRate(TimerTask task, long delay, long period)只能执行固定周期的任务,所以不可以动态地调整周期。若想

要动态调整,则需要在执行玩一个定时器任务后,再启动一个新的任务时设置新的时间。

UI界面更新 Handler:在创建的时候可以指定所在的线程,一般在Activity中构建的,即主线程上,所以可以在回调方法中很方便的更新

界面。 Timer:异步回调,所以必须借助Handler去更新界面,不方便。  既然都得用Handler去更新界面了,为何不如把定时的功能也交

给

Handler去做呢?

二.内存占比

Timer比Handler更占内存。接下来的Demo例子通过两种方法循环地打印日志,然后通过MAT插件来查看这两个类所需要调用的对象所产生的

占比。

int mCount = 0;
private void startTimer() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Log.i("JKL", "" + mCount);
mCount++;
}
}, 0, 200);
}
private void startHandler() {
final Handler mHandler = new Handler();
mHandler.post(new Runnable() {
@Override
public void run() {
Log.i("JKL", "" + mCount);
mCount++;
mHandler.postDelayed(this, 200);
}
});
}

可以通过创建一个新的Android工程,在onCreate方法中调用以上startTimer或startHandler任意一个方法来测试。以下是MAT的测试结果。

Timer相关对象的内存占比

共有5个对象,占用1192B。Handler相关对象的内存占比

我们可以看到上面有2个Handler,这时候你是否会疑惑呢?其实一个是我们生成的Handler,另外一个是Activity默认生成的,存在于ViewRootImp中,这涉及到ViewTree的知识,此处不便展开。

不过我们可以知道,我们自己构建的Handler,最多也就只占64B。

在使用Handler的时候,还需要用到Runnable,不过也只占了16B。所以,使用Handler的方式来作为定时器,最多也就是80B。

以上可以得出结论,相比起Timer方式的定时器占用1192B,Handler的方式占用资源会小很多,只有1/60。

所以Handler的方式比较节省内存。

写到这里,想到一个点,Timer是创建一个线程去计数的,而Handler是在默认主线程运行的。假若Handler也用一个异步线程去运行,会不会耗很多资源呢?以下是测试代码:

private void startHandler() {
HandlerThread thread = new HandlerThread("Test");
thread.start();
final Handler mHandler = new Handler(thread.getLooper());
mHandler.post(new Runnable() {
@Override
public void run() {
Log.i("JKL", "" + mCount);
mCount++;
mHandler.postDelayed(this, 200);
}
});
}

以上用一个HandlerThread来启动一个新的线程。再看看内存占比

以看到HandlerThread也只是占了96B的内存。

综上所述,Handler内存占比低!而且低了不少。

无论从易用性还是内存占比出发,Handler更胜一筹

android Handler vs Timer的更多相关文章

  1. Android Handler的使用

    大家好我们这一节讲的是Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title. 首先我们看一下习惯了Java编程的人,在不知道Handl ...

  2. Android Handler的简单使用

    大家好我们这一节讲的是Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title. 首先我们看一下习惯了Java编程的人,在不知道Handl ...

  3. Android Handler 消息处理使用

    本文内容 环境 演示 Handler 消息处理 参考资料 Handler 有两个主要作用或者说是步骤:发送消息和处理消息.在新启动的线程中发送消息,在主线程中获取.并处理消息.Android 平台只允 ...

  4. Handler vs Timer,究竟该用哪个?

    Handler vs Timer 在我们Android开发过程中,经常需要执行一些短周期的定时任务,这时候有两个选择Timer或者Handler.然而个人认为:Handler在多个方面比Timer更为 ...

  5. iOS中的NSTimer 和 Android 中的Timer

    首先看iOS的, Scheduling Timers in Run Loops A timer object can be registered in only one run loop at a t ...

  6. Android Handler leak 分析及解决办法

    In Android, Handler classes should be static or leaks might occur, Messages enqueued on the applicat ...

  7. Android Handler练习

    package com.example.myact12; import java.util.Random; import android.support.v7.app.ActionBarActivit ...

  8. Android Handler简单使用

    package com.example.myhandlertest3; import android.os.Bundle; import android.os.Handler; import andr ...

  9. [Android]Handler的消息机制

    最经面试中,技术面试中有一个是Handler的消息机制,细细想想,我经常用到的Handler无非是在主线程(或者说Activity)新建一个Handler对象,另外一个Thread是异步加载数据,同时 ...

随机推荐

  1. Java中的字面量

    在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(natation).几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数.浮点数以及字符串:而有很多也对布尔类型和 ...

  2. js 常用插件

    文本输入框 计算器 <html> <head> <meta http-equiv="Content-Type" content="text/ ...

  3. GO interface显示类型转换方法

    一共两种,直接看代码 import ( "fmt") func main() { //var i interface{} = "TT" var i interf ...

  4. android 简单粗暴的注解初始化View学习

    原理是在Activity加载好后通过找到Activity中使用注解的字段,再通过Java反射的方式,动态的给这个字段设置值. 1定义一个注解接口 /** * view inect by id * * ...

  5. 在Ubuntu 14.04安装 Let’s Encrypt并配置ssl

    1.下载安装 Let's Encrypt客户端 cd /usr/local/sbin sudo wget https://dl.eff.org/certbot-auto 2.添加执行权限 sudo c ...

  6. Oracle第二天

    Oracle第二天 整体安排(3天) 第一天:Oracle的安装配置(服务端和客户端),SQL增强(单表查询). 第二天:SQL增强(多表查询.子查询.伪列-分页),数据库对象(表.约束.序列),Or ...

  7. EMPTY isset unset var_dump 用法

    empty    判断一个变量是否为空,返回布尔值  isset  isset 判断一个值是否存在  unset取消变量设置, var_dump 打印变量并类型

  8. MySQL中整型数据的差别

    bigint 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字).存储大小为 8 个字节. P.S. b ...

  9. IOS 中会发生crash的操作

    对字典和数组进行下列操作时会产生crash: 对于字典来说: 查询时,key=nil 或者 key=null 时都能正常运行 插入时,,key=nil 或者 key=null 都会crash 对于数组 ...

  10. 如何安全退出已调用多个Activity的Application?

    如何退出Activity?如何安全退出已调用多个Activity的Application? 退出Activity直接调用finish()方法  //用户点击back键就是退出一个Activity 退出 ...