定时任务 Handler vs Timer
来源:互联网 发布:淘宝加盟要多少钱 编辑:程序博客网 时间:2024/06/02 02:19
前言
Android开发过程中,经常需要执行一些短周期的定时任务,这时候有两个选择Timer或者Handler。很多朋友都会为选择哪种方案最优而犹豫为难,今天我们做一下比较,希望对各位以后开发都有一定的参考价值。(也是自己在网上优秀资料学习的一些整理吧,转自博客园,作者:Benhero,博客地址:http://www.cnblogs.com/benhero/)
一.易用性
1. 可重复执行
Handler可以重复执行某个任务。
Timer若在某个任务执行/取消之后,再次执行则会抛出一个IllegalStateException异常。为了避免这个异常,需要重新创建一个Timer对象。
2. 周期可调整
若想要执行一个越来越快的定时任务,Handler可以做到,而Timer则消耗较大。
Handlerprivate 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)只能执行固定周期的任务,所以不可以动态地调整周期。若想要动态调整,则需要在执行玩一个定时器任务后,再启动一个新的任务时设置新的时间。
3. 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更胜一筹.
- 定时任务:Handler vs Timer
- 定时任务 Handler vs Timer
- Handler vs Timer
- Handler vs Timer
- java Timer 定时任务
- Java定时任务Timer
- JAVA定时任务Timer
- timer定时任务
- 定时任务 Timer
- timer定时任务
- Timer定时任务
- Java 定时任务Timer
- Timer 定时任务
- Java定时任务Timer
- TimerTask、Timer 定时任务
- 定时任务--Timer()实现
- java Timer 定时任务
- java 定时任务Timer
- LeetCode (28)Implement strStr()
- 第九周OJ-Q16解题方法
- cocos2dx-lua基础内容之 坐标系的转换
- 第四章 栈
- 【STM32烧写方法二】RS232-TTL(用于有些芯片的JTAG和SWD端口被禁止烧写的解决)
- 定时任务 Handler vs Timer
- 在ROS中使用USB网络摄像头传输图像
- 简易电话簿实现一(静态)
- Android 横向条形统计图
- 自定义进度条渐变色进度条
- 516. Longest Palindromic Subsequence
- Spring 配置 hbase
- MySQLFront导入SQL文件报#1113错误解决
- Gradle+Spring Boot+Git+Docker构建web服务