android 定时器(Handler Timer Thread AlarmManager CountDownTimer)
Android实现定时任务一般会使用以上(Handler Timer Thread AlarmManager CountDownTimer)五种方式。当然还有很多组合使用(比如Handler+Thread 比如Handler类自带的postDelyed 比如Handler+Timer+TimerTask)的方式就不一一说明了,知道了每个小部分的使用结合起来使用当然就不是问题啦。
本文以简单的实现1s让数字加1的一个小实例。(考虑只点击一次的情况。连续点击 需要控制没有结束的时候 不许点击的逻辑)
一:使用Handler:
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == 1){
Log.e(TAG,"mHandler"+Thread.currentThread().getName());
tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
mHandler.sendEmptyMessageDelayed(1,1000);
}
}
};
在点击事件的时候 调用 mHandler.sendEmptyMessageDelayed(1,1000);可以使用 mHandler.removeMessages(1);取消handler。
二:使用Timer。使用Timer的时候要用到TimerTask。也是很简单的使用:
private void timer() {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Log.e(TAG, "Timer:"+Thread.currentThread().getName());
runOnUiThread(new Runnable() {
@Override
public void run() {
tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
}
});
}
}, 1000, 1000);
}
点击的时候就直接调用这个方法就好了。前面一个1000表示多久之后开始执行。后面的1000表示多久执行一次。其他的同名重载函数。看方法名就知道每个函数的作用了。
三:使用Thread,使用这个个人感觉和Timer差不多。都是开一个线程+延时操作。所以更新UI的时候必须在主线程。
private MyThread thread;
private class MyThread extends Thread {
public boolean stop;
public void run() {
while (!stop) {
// 通过睡眠线程来设置定时时间
try {
Thread.sleep(1000);
Log.e(TAG, "Thread:"+Thread.currentThread().getName());
runOnUiThread(new Runnable() {
@Override
public void run() {
tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
};
private void startThread() { //开始线程
if (thread == null) {
thread = new MyThread();
thread.start();
}
}
private void stopThread() { //结束线程
if (thread != null) {
thread.stop = true;
thread = null;
}
}
点击时间调用startThread()就好了。
四:使用alarmService。其实通过AlarmManager来实现的。AlarmManager在安卓中最常见使用的地方就是闹钟。看这个的名字就知道是启动一个系统级服务来完成的。贴代码:
private String ACTION_NAME = "alarmService";
private void alarmServiceStart(){
//注册广播
registerBoradcastReceiver();
//启动AlarmManager
Intent intent =new Intent(ACTION_NAME);
PendingIntent sender=PendingIntent
.getBroadcast(this, 0, intent, 0);
long firstime= SystemClock.elapsedRealtime();
AlarmManager am=(AlarmManager)getSystemService(ALARM_SERVICE);
//5秒一个周期,不停的发送广播
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP
, firstime,1000, sender);
}
//注册广播
public void registerBoradcastReceiver(){
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(ACTION_NAME);
registerReceiver(mBroadcastReceiver, myIntentFilter);
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(ACTION_NAME)){
tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
}
}
};
五:CountDownTimer:这个其实是android封装好的一个倒计时类。用法特别方便:如下
/**
* 使用CountDownTimer 其实是android封装好的 倒计时类
* 说明这里的10*1000表示总时间 也就是10s 1000表示多久执行一次
*/
private CountDownTimer countDownTimer = new CountDownTimer(10*1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
}
@Override
public void onFinish() {
tvNum.setText("执行结束");
}
};
总结:用法其实都是很简单的。但是就是因为有很多种方法实现不知道使用哪一种。个人建议:
1,使用倒计时(限时特卖时间倒计时,获取验证码倒计时)可以使用第五种方法实现。(不考虑自定义组件)
2,图片的轮播,banner之类的可以使用Handler和Timer(Thread差不多)。实现定时滑动。(不考虑自定义组件)
3.使用一些对特定时间执行要求比较严格的时候使用alarmService。这里说明一下:Android系统锁的机制,即系统在检测到一段时间没有活跃以后,会关闭一些不必要的服务来减少资源和电量消耗。使用Timer和Service来实现的话很可能出现的情况就是屏幕熄灭后一段时间,服务就被停止了,当然轮询也就被停止了。当前轮播停止对我们影响不大。但是某种特定的情况停止了可以造成很大的损失。比如闹钟:停止了你还能起来吗?
这里还有一点就是第四种am的setRepeating方法。设置类型为AlarmManager.ELAPSED_REALTIME时候 当应用休眠的时候 也不会执行定时任务。设置类型为AlarmManager.ELAPSED_REALTIME_WAKEUP的时候 就会一直执行。
以上观点都是我的个人看法。如果有不对的地方 忘大神指教。有没有注意到的地方也忘大神指教
附上项目的github地址 https://github.com/tozzais/AndroidTimingTest
android 定时器(Handler Timer Thread AlarmManager CountDownTimer)的更多相关文章
- Android中Handler 、Thread和Runnable之间的关系
在多线程编程的时候,我们经常会用到Handler,Thread和Runnable这三个类,我们来看看这三个类之间是怎么样的关系? 首先说明Android的CPU分配的最小单元是线程,Handler一般 ...
- Android Exception 13(Can't create handler inside thread that has not called Looper.prepare())
10-12 17:02:55.500: E/AndroidRuntime(28343): FATAL EXCEPTION: Timer-2 10-12 17:02:55.500: E/AndroidR ...
- Android 定时器Timer的使用
定时器有什么用 在我们Android客户端上有时候可能有些任务不是当时就执行,而是过了一个规定的时间在执行此次任务.那么这个时候定时器的作用就非常有用了.首先开启一个简单的定时器 Timer time ...
- Android笔记——Handler Runnable与Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- Android 线程更新UI报错 : Can't create handler inside thread that has not called Looper.prepare()
MainActivity中有一个按钮,绑定了save方法 public void save(View view) { String title = titleText.getText().toStri ...
- android 定时器AlarmManager
1.android中通常是使用AlarmManager来定时启动一个单次或重复多次操作的.具体的说就是我们通过AlarmManager设定一个时间和注册一个intent到系统中,然后在该时间到来时,系 ...
- Android handler 报错处理Can't create handler inside thread that has not called Looper.prepare()
问题: 写了一个sdk给其他人用,提供一个回调函数,函数使用了handler处理消息 // handler监听网络请求,完成后操作回调函数 final Handler trigerGfHandler ...
- ANDROID_MARS学习笔记_S04_009_用java.lang.ref.SoftReference作缓存,android.os.Handler和new Thread异步加载略图片
一.简介 二.代码流程 1.private Map<String, SoftReference<Drawable>> imageCache = new HashMap<S ...
- Android 多线程:使用Thread和Handler
当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分 ...
随机推荐
- Android -- 带你从源码角度领悟Dagger2入门到放弃(二)
1,接着我们上一篇继续介绍,在上一篇我们介绍了简单的@Inject和@Component的结合使用,现在我们继续以老师和学生的例子,我们知道学生上课的时候都会有书籍来辅助听课,先来看看我们之前的Stu ...
- STM32F0的flash读写
flash大小64k Rom+8k Ram的大小,stm32f051有64k Rom,总的分为 64页,一页1024byte ,在flash的Rom里面写数据掉电保存,相当于W25q80 uint32 ...
- 关于Java内存管理的几个小技巧
这里将介绍几则Java内存管理的小技巧,让你让你从Java入门开始告别陋习,为Java程序提速.有不少人都说"Java完了,只等着衰亡吧!",为什么呢?最简单的的例子就是Java做 ...
- [codevs]1060搞笑世界杯
CODEVS上一道钻石题,还是DP的思想,先来题目 1060 搞笑世界杯 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description ...
- 【原创】Android 5.0 BLE低功耗蓝牙从设备应用
如果各位觉得有用,转载+个出处. 现如今安卓的低功耗蓝牙应用十分普遍了,智能手环.手表遍地都是,基本都是利用BLE通信来交互数据.BLE基本在安卓.IOS两大终端设备上都有很好支持,所以有很好发展前景 ...
- 阿里云CentOS-7.2安装mysql
我下载的阿里云的服务器系统centos7.2是纯内核版本,并没有其他的工具,所以这个系统是非常干净的.所以我就需要给系统安装一一些工具,来方便系统的管理与操作,我们上面讲到了关于服务器的yum的配置在 ...
- TypeScript入门-枚举、类型推论
枚举 使用枚举可以定义一些具有名字的数字常量,和在C语言中一样都是使用关键字enum enum Direction { Up = 1, Down = 1<<2, Left, Right } ...
- OC中的copy
copy的概念 Copy的字面意思是"复制"."拷贝",是一个产生副本的过程 对象拷贝的目的:要使用某个对象的数据,但是在修改对象的时候不影响原来的对象内容,常 ...
- 工具类总结---(三)---MD5加密
用于给文件名等进行MD5加密: import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; / ...
- hdu 4552 怪盗基德的挑战书
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4552 思路: 其实可以用KMP+DP解决 我这里给出后缀数组的解题方法 思路: 初始化ans=n(n为 ...