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)的更多相关文章

  1. Android中Handler 、Thread和Runnable之间的关系

    在多线程编程的时候,我们经常会用到Handler,Thread和Runnable这三个类,我们来看看这三个类之间是怎么样的关系? 首先说明Android的CPU分配的最小单元是线程,Handler一般 ...

  2. 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 ...

  3. Android 定时器Timer的使用

    定时器有什么用 在我们Android客户端上有时候可能有些任务不是当时就执行,而是过了一个规定的时间在执行此次任务.那么这个时候定时器的作用就非常有用了.首先开启一个简单的定时器 Timer time ...

  4. Android笔记——Handler Runnable与Thread的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  5. 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 ...

  6. android 定时器AlarmManager

    1.android中通常是使用AlarmManager来定时启动一个单次或重复多次操作的.具体的说就是我们通过AlarmManager设定一个时间和注册一个intent到系统中,然后在该时间到来时,系 ...

  7. Android handler 报错处理Can't create handler inside thread that has not called Looper.prepare()

    问题: 写了一个sdk给其他人用,提供一个回调函数,函数使用了handler处理消息 // handler监听网络请求,完成后操作回调函数 final Handler trigerGfHandler ...

  8. ANDROID_MARS学习笔记_S04_009_用java.lang.ref.SoftReference作缓存,android.os.Handler和new Thread异步加载略图片

    一.简介 二.代码流程 1.private Map<String, SoftReference<Drawable>> imageCache = new HashMap<S ...

  9. Android 多线程:使用Thread和Handler

    当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分 ...

随机推荐

  1. Lambda表达式效率问题

    原文 http://www.importnew.com/17262.html 有许许多多关于 Java 8 中流效率的讨论,但根据 Alex Zhitnitsky 的测试结果显示:坚持使用传统的 Ja ...

  2. IDEA第一章----下载安装idea,设置背景字体编码,配置JDK/Maven

    写在前面的话: 在程序的世界混迹了5年+,认真过,蹉跎过,回首突然发现自己得到的东西却很少.于是想写点东西记录下学习.工作抑或生活的种种,人生不只是眼前的苟且还有诗和远方,任沧海桑田韶华不在,愿无岁月 ...

  3. python自动化测试应用-番外篇--接口测试2

    篇2                 book-python-auto-test-番外篇--接口测试2 --lamecho辣么丑 大家好! 我是lamecho(辣么丑),今天将继续上一篇python接 ...

  4. 金山助手流氓软件-被进程sjk_daemon.exe坑死

    修改完Android工程代码,进入调试阶段时DDMS中报错:The connection to adb is down, and a severe error has occured. 由于之前也碰到 ...

  5. Openstack Swift 原理、架构与 API 介绍

    OpenStack Swift 开源项目提供了弹性可伸缩.高可用的分布式对象存储服务,适合存储大规模非结构化数据.本文将深入介绍 Swift 的基本设计原理.对称式的系统架构和 RESTful API ...

  6. Mycil命令行MySQL语法高亮和自动补全工具

    MyCli 是MySQL,MariaDB和Percona的命令行界面,具有自动完成和语法高亮的功能. 其效果如图: 那么我们应该怎么安装它呢,这里附上windows的安装方法. 在命令行下输入 pip ...

  7. Visual Lisp获得网络时间的方法

    (defun c:tt (/ ie-obj) (setq ie-obj (vlax-get-or-create-object "Msxml2.xmlhttp")) ) (vlax- ...

  8. Java学习笔记——排序算法之快速排序

    会当凌绝顶,一览众山小. --望岳 如果说有哪个排序算法不能不会,那就是快速排序(Quick Sort)了 快速排序简单而高效,是最适合学习的进阶排序算法. 直接上代码: public class Q ...

  9. 让人恼火的经历——手机H5网页被注入广告

    你的网站是否在尾部出现了让人恼火的广告? 这次我算是遇到了这些流氓的广告.那么就让我们一步步攻克这些恼火的广告吧. 问题描述 某一天下午开始,我们制作的网站就开始被各种广告注入,类似上图这种. 还有在 ...

  10. 你真的用好了Python的random模块吗?

    random模块 用于生成伪随机数 源码位置: Lib/random.py(看看就好,千万别随便修改) 真正意义上的随机数(或者随机事件)在某次产生过程中是按照实验过程中表现的分布概率随机产生的,其结 ...