利用Service实现——定时任务

功能:实现通过按钮开启服务,在服务中延迟10秒去开启广播,在广播接收中又去开启服务,实现循环

主要是通过AlarmManager实现延迟  (警告管理)

通过按钮开启服务:

/**
 * 实现定时功能
 用于指定 AlarmManager的工作类型,有四种值可选
ELAPSED_REALTIME:            表示让定时任务的触发时间从系统开机开始算起,但不会唤醒 CPU。
ELAPSED_REALTIME_WAKEUP: 同样表示让定时任务的触发时间从系统开机开始算起,但会唤醒 CPU。
RTC :                       表示让定时任务的触发时间从 1970 年 1月 1 日 0 点开始算起,但不会唤醒 CPU
RTC_WAKEUP:                  表示让定时任务的触发时间从1970 年 1 月 1 日 0 点开始算起,但会唤醒 CPU。
使用 SystemClock.elapsedRealtime()方法可以获取到系统开机至今所经历时间的毫秒数,(所以与ELAPSED_REALTIME_WAKEUP模式一起使用)
使用 System.currentTimeMillis()方法可以获取到 1970 年 1 月 1 日 0 点至今所经历时间的毫秒数。(所以与RTC_WAKEUP模式一起使用)
new Date().toString());//获取当前时间(包括日期,详细信息)
 */
public class MainActivity2_Text extends Activity {
    private Button btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main2_layout);
        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity2_Text.this,AlarmService.class);
                startService(intent);//开启服务
            }
        });
    }
}

服务类:

public class AlarmService extends Service{

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable(){
            @Override
            public void run() {//可以在该线程中做需要处理的事
                System.out.println("当前时间:"+new Date().toString());//获取日期时间
                stopSelf();//关闭服务
            }
        }).start();
        AlarmManager manger=(AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent i=new Intent(this,AlarmReceiver.class);//广播接收
        //PendingIntent pendingIntent=PendingIntent.getActivity(MainActivity2_Text.this, 0, intent, 0);//意图为开启活动
        PendingIntent pendingIntent=PendingIntent.getBroadcast(this, 0, i, 0);//意图为开启广播
        long triggerAtTime = SystemClock.elapsedRealtime();//开机至今的时间毫秒数
        triggerAtTime=triggerAtTime+10*1000;//比开机至今的时间增长10秒
        manger.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);//设置为开机至今的模式,时间,PendingIntent
        return super.onStartCommand(intent, flags, startId);
    }    
}

说明:以上在子线程中只是打印了一条当前时间,你也可以去执行你想要做的事

另外需要注意的是,从 Android 4.4 版本开始,Alarm 任务的触发时间将会变得不准确
有可能会延迟一段时间后任务才能得到执行。这并不是个 bug,而是系统在耗电性方面进行
的优化。系统会自动检测目前有多少 Alarm 任务存在,然后将触发时间将近的几个任务放在
一起执行,这就可以大幅度地减少 CPU 被唤醒的次数,从而有效延长电池的使用时间。
当然,如果你要求 Alarm 任务的执行时间必须准备无误,Android 仍然提供了解决方案。
使用 AlarmManager 的 setExact()方法来替代 set()方法,就可以保证任务准时执行了。

 

上面代码中服务类开启的广播接收器:

public class AlarmReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("接收到意图开启的广播,当前时间为:"+new Date().toString());
        Intent i=new Intent(context,AlarmService.class);
        context.startService(i);//开启AlarmService服务
    }
}

由于用到了广播与服务,所以需要注册,如下:

<service android:name="com.example.ts.service.AlarmService"></service>
<receiver android:name="com.example.ts.service.AlarmReceiver"></receiver>

输出效果如图:

 

posted @ 2016-04-28 19:45  ts-android  阅读(3757)  评论(0编辑  收藏  举报