美文网首页
Android定时任务

Android定时任务

作者: 黄烨1121 | 来源:发表于2017-11-22 15:32 被阅读0次

本章目录

  • Part One:Timer
  • Part Two:AlarmManager

Android中有很多种实现定时任务的方式,比如Timer,CountDownTimer, AlarmManager,handler和Thread。不过,主要常用的有三种:

  1. Timer(Java遗留的)
  2. Handler(下雪动画那篇使用过了)
  3. AlarmManager(Android官方推荐)

Part One:Timer

Timer是一个定时器工具,包含一系列的schedule方法用于实施定时计划。TimerTask是一个子线程的抽象类,方便在后台处理一些比较复杂的逻辑,然后利用Handler在主线程刷新UI。
下面我们通过修改先前的案例来认识一下这两个类的具体应用。

  • 首先,在activity_main.xml的cacheContainer_main布局容器中,放一个TextView,用来显示滚动文字。
        <TextView
            android:id="@+id/textView_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:textColor="@android:color/white"
            android:layout_marginBottom="64dp"/>
  • 然后在MainActivity里面初始化这个TextView和SnowView(这里初始化SnowView是用来关闭自定义View的绘制)。
    private TextView textView;
    private SnowView snowView;
    
    private void initViews() {
        cacheContainer = findViewById(R.id.cacheContainer_main);
        animContainer = findViewById(R.id.animContainer_main);
        leftAnimImageView = findViewById(R.id.leftAnimContainer_main);
        rightAnimImageView = findViewById(R.id.rightAnimContainer_main);
        textView = findViewById(R.id.textView_main);
        snowView = findViewById(R.id.snowView_main);
    }
  • 接着初始化一段文字数组,用来以滚动的方式,不断更新显示的文字。
    private String[] contents = new String[]{"时间久了,我都快忘记我们相识多少年了,",
            "我只知道我认识你很久了,", "漫长的时间却拉不近我们的距离,",
            "一天一点爱恋,一夜一点思念,", "不想再等了,有些话想对你说。"};
  • 最后,把先前定义的openWindow方法改成switchContent,让方法名字表达的更准确一些。同时在方法里初始化Timer和TimerTask,并调用相应的方法。
    private int index = 0;//数组的索引,用于让TextView显示不同内容,初识从0开始
    private void switchContent() {
        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //刷新UI必须执行在主线程
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //如果字符串数组全部显示完毕,下标清0,防止越界。同是,让自定义View停止绘制。
                        //Timer停止计划任务,并执行开窗动画
                        if (index == contents.length){
                            index = 0;
                            snowView.stopDraw();
                            initCache();
                            timer.cancel();
                        }
                        //让TextView滚动显示文字
                        textView.setText(contents[index]);
                        index++;
                    }
                });
            }
        }, 50, 4000);
    }

整个计划任务的实现逻辑并不复杂,就是不断变换数组索引坐标,让TextView显示不同的内容。
这里要重点说一下我们使用的timer.schedule(task, delay, period)的三个参数:

  1. task:TimerTask对象,就是要周期执行的任务。
  2. delay:从计时器初始化完毕后,开始启动的延迟时间。
  3. period:定时器的间隔时间。
    比如,我们的案例就是50毫秒后启动定时器,没4秒更新一下文字,文字刷新完执行动画。


    滚动文字.gif

Part Two:AlarmManager

前面提到的Timer实现定时任务的方式使用的是Java的API,大部分情况下都是满足需求的,比如本例。但是如果遇到手机锁屏或者关机,唤醒CPU执行定时任务时,就会遇到一些问题,比如闹钟。所以,官方推荐使用AlrmManager来执行定时任务。
AlarmManager的实现方式也不是很复杂,只是需要用到PendingIntent,具体步骤如下:

  • 先前的准备工作不变,只是改变switchContent方法。首先,注释掉先前写的代码,然后声明一个全局的AlarmManager
    private void switchContent() {
        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    }

    private AlarmManager alarmManager;
  • 然后声明一个全局的PendingIntent,并设置AlarmManager的重复方式
    private void switchContent() {
        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent intent = new Intent();
        intent.setAction("action.REFRESHTEXTVIEW");
        pendingIntent = PendingIntent.getBroadcast(this,
                100, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                5000, 60000, pendingIntent);
    }

    private AlarmManager alarmManager;
    private PendingIntent pendingIntent;

其中,PendingIntent是个延迟意图对象,这里是发送广播,所以使用getBroadcast方法,也可以使用getService启动Service或者getActivity启动Activity来执行某项固定任务。getBroadcast的参数前面都好理解,最后一个参数的效果有:

  1. FLAG_CANCEL_CURRENT:如果系统中有一个相同的PendingIntent对象,那么就取消旧的,然后重新生成一个。
  2. FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。
  3. FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
  4. FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。
    另外,setRepeating也需要注意,从Android5.0开始,第二个参数triggerAtMillis(触发时间)不得低于5秒,intervalMillis(重复间隔)不得低于60秒。这两个参数如果比这两个值小,默认分别是5秒和60秒,只有大于才会生效,因为间隔太短会费电~短时间的定时任务,官方推荐使用Handler方式。
    所以,其实AlarmManager并不适合本例,这里只是讲一下用法。
    setRepeating方法的第一个参数也单独说下:
  5. AlarmManager.RTC_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
  6. AlarmManager.RTC表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
  7. AlarmManager.ELAPSED_REALTIME_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
  8. AlarmManager.ELAPSED_REALTIME表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
  9. AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;
  • 接下来就是自定义一个广播接收者,当接收到广播时,执行的任务:
    private class AlarmBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (index == contents.length) {
                index = 0;
                snowView.stopDraw();
                initCache();
                alarmManager.cancel(pendingIntent);//取消定时器
            }
            //让TextView滚动显示文字
            textView.setText(contents[index]);
            index++;
        }
    }
  • 最后,将广播注册即可
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("action.REFRESHTEXTVIEW");
        BroadcastReceiver receiver = new AlarmBroadcastReceiver();
        registerReceiver(receiver, intentFilter);

结果就是每隔60秒发送一个广播,广播接收器收到广播后,执行相应的任务。

相关文章

  • Android定时任务

    创建定时任务解决打盹问题,但是会在后台不断唤醒cpu,可能对设备续航有一些影响。 Alarm模式(警报模式):An...

  • android定时任务

    Android中几种定时器的总结和比较 - 爱悠闲 采用Handler与线程的sleep(long)方法 采用H...

  • Android定时任务

    参考:Android中定时器的3种实现方法 Thread.sleep java的方式,不推荐sleep使线程暂停,...

  • Android定时任务

    android中定时有很多种是实现,常见的Handler 与Thread的结合,handler.postDelay...

  • Android定时任务

    本章目录 Part One:Timer Part Two:AlarmManager Android中有很多种实现定...

  • Android定时任务

    前言 最近项目上有这么一个需求,实时监控车辆信息,要求每隔3秒钟刷新一次地图上的车辆位置信息。我的想法是先定时从服...

  • 后台执行的定时任务

    另可参考:Android 定时任务的多种实现方式 Android 中的定时任务一般有两种实现方式,一种是使用 Ja...

  • 定时任务之Alarm

    之前我们已经简单说了定时任务的几种方式,详见:定时任务今天我们来看看如何用Android的Alarm机制来做定时任...

  • Timer 实现倒计时功能

    Android 定时器 在Android开发中有些任务是需要通过延时来完成的,这个时候就用到了定时器Timer

  • Java多线程学习之定时器 Timer

    定时 / 计划功能 定时 / 计划功能在移动开发领域使用较多,比如 Android 技术。定时计划任务功能在 Ja...

网友评论

      本文标题:Android定时任务

      本文链接:https://www.haomeiwen.com/subject/idgnvxtx.html