AlarmManager+BroadcastReceiver+Service实现后台循环定时器
2018-01-16 15:40
1586 查看
为了判断在线用户数,项目APP要实现一个心跳包的操作。就是在APP运行的时候每隔一段时间发送一个请求到后台,后台根据你发送的信息而得知你是在线用户。
一开始我是使用了Timer定时器来实现这个操作,主要代码如下:
这样做一眼看上去并没有什么问题,但是实际运用后才发现,当手机锁屏后,定时器会暂停,也就是说不再定时执行任务,直到重新开启屏幕后才会继续执行,这涉及到Android的休眠策略,
这就蛋疼了,所以简单的查了一下资料我就直接抛弃了Timer定时器。准备使用AlarmManager,这是Android中常用的一种系统级别的提示服务,想了解具体可以自行百度。当然,既然要在锁屏后仍然运行,就涉及到后台服务了,所以这里我使用了一个service;当然在使用AlarmManager这个定时器时也有一些小问题,比如在不同版本的休眠策略中,使用AlarmManager会出现定是不准确的问题,还有6.0之后适配的问题。查了不少资料,基本上都解决了以上问题。下面直接上代码:
LongRunningService.java
//service主要就是能够后台运行
MyBroadcastReceiver.java
//自定义广播,接收数据,在这里执行定时后要执行的操作
public class MyBroadcastReceiver extends BroadcastReceiver {
}
最后别忘了在AndroidManifest.xml中注册
通过上面一个简单的后台循环定时器就实现了
有更好的方法欢迎讨论。
居然不能选择免费,要demo可以留言
DeMo
一开始我是使用了Timer定时器来实现这个操作,主要代码如下:
public class TimerMethod { private static TimerMethod instance = null; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); { switch (msg.what) { case 1: //执行定时后的对应操作 break; } } } }; private Timer mTimer; private long count = 900000; private TimerTask mTimerTask; private TimerMethod() { } public static TimerMethod getInstance() { if (instance == null) { instance = new TimerMethod(); } return instance; } //单例模式调用定时器,根据isTimer判断启动还是关闭定时器。一旦开启后定时器回根据count的时间循环执行 public void exce(boolean isTimer, int count, String token) { stopTimer(); if (isTimer) { startTimer(count); } } //启动定时器 private void startTimer(int count) { if (count != -1) { this.count = count; } if (mTimer == null) { mTimer = new Timer(); } if (mTimerTask == null) { mTimerTask = new TimerTask() { @Override public void run() { Message message = new Message(); message.what = 1; handler.sendMessage(message); } }; if (mTimer != null && mTimerTask != null) { mTimer.schedule(mTimerTask, this.count, this.count); } } } //停止定时器 private void stopTimer() { if (mTimer != null) { mTimer.cancel(); mTimer = null; } if (mTimerTask != null) { mTimerTask.cancel(); mTimerTask = null; } } public Timer getTimer() { return this.mTimer; } }
这样做一眼看上去并没有什么问题,但是实际运用后才发现,当手机锁屏后,定时器会暂停,也就是说不再定时执行任务,直到重新开启屏幕后才会继续执行,这涉及到Android的休眠策略,
这就蛋疼了,所以简单的查了一下资料我就直接抛弃了Timer定时器。准备使用AlarmManager,这是Android中常用的一种系统级别的提示服务,想了解具体可以自行百度。当然,既然要在锁屏后仍然运行,就涉及到后台服务了,所以这里我使用了一个service;当然在使用AlarmManager这个定时器时也有一些小问题,比如在不同版本的休眠策略中,使用AlarmManager会出现定是不准确的问题,还有6.0之后适配的问题。查了不少资料,基本上都解决了以上问题。下面直接上代码:
MainActivity.java //这里我只是用一个例子,简单的实现启动和关闭定时器 @Override public void onClick(View view) { switch (view.getId()){ case R.id.btn_open: //启动定时器 int time = new Integer(editText.getText().toString().trim()); Log.d("print", "onClick: "+time); Intent intent = new Intent(this, LongRunningService.class); intent.putExtra("time", time * 60000); //传入定时时间 startService(intent); break; case R.id.btn_close: //关闭定时器 Intent intentService = new Intent(this, LongRunningService.class); AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); Intent intent1 = new Intent("ELITOR_CLOCK"); PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent1, 0); manager.cancel(pi); stopService(intentService); break; } }
LongRunningService.java
//service主要就是能够后台运行
public class LongRunningService extends Service { private static int anHour = 60000; private AlarmManager manager; @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { anHour = intent.getIntExtra("time", anHour); manager = (AlarmManager) getSystemService(ALARM_SERVICE); long triggerAtTime = SystemClock.elapsedRealtime() + anHour; Intent intent1 = new Intent("ELITOR_CLOCK"); PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent1, 0); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); } else { manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); } return super.onStartCommand(intent, flags, startId); } }
MyBroadcastReceiver.java
//自定义广播,接收数据,在这里执行定时后要执行的操作
public class MyBroadcastReceiver extends BroadcastReceiver {
private static int ikk = 0; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.e("Receiver:", action); switch (action) { case "ELITOR_CLOCK": Log.d("print", "onReceive: 执行成功" + ikk++); //执行对应的操作 //因为定时器是一次性的,在执行操作后重启定时器就可以达到循环执行 Intent intent1 = new Intent(context, LongRunningService.class); context.startService(intent1); break; default: break; } }
}
最后别忘了在AndroidManifest.xml中注册
<service android:name=".LongRunningService"/> <receiver android:name=".MyBroadcastReceiver" android:enabled="true"> <intent-filter> <action android:name="ELITOR_CLOCK"/> </intent-filter> </receiver>
通过上面一个简单的后台循环定时器就实现了
有更好的方法欢迎讨论。
居然不能选择免费,要demo可以留言
DeMo
相关文章推荐
- Android实现闹钟,通过AlarmManager+BroadcastReceiver(广播)
- 使用IntentService与BroadcastReceiver实现后台服务(Android7.0可用)
- 关于android实现聊天: Service +BroadcastReceiver
- Service、Alarm与BroadcastReceiver的使用方法
- notification+service+broadcastreceiver实现简单的音乐播放器
- Android后台处理最佳实践(IntentService,LocalBroadcastManager)
- 使用Service+BroadcastReceiver实现定时更新天气
- Android杂谈(24)Service+BroadcastReceiver+数据库+HttpURLConnection实现断点续传(下)
- Android 利用Service BroadcastReceiver实现小例子
- 关于android实现聊天: Service +BroadcastReceiver
- Using AlarmManager and BroadcastReceiver in Android
- Android杂谈(23)Service+BroadcastReceiver+数据库+HttpURLConnection实现断点续传(上)
- android音乐播放器实现(Service+BroadcastReceiver+Notification)
- 通过BroadcastReceiver和 service 实现开机自动启动
- 利用IntentService实现在broadcastreceiver中比较耗时的任务
- 【总结备用】Android监听网络状态实现(BroadcastReceiver + Service)
- Android监听网络状态实现(BroadcastReceiver + Service)
- service 和broadcastreceiver的简略小结
- activity、 intent 、intent filter、service、Broadcast、BroadcaseReceiver解释
- android轮询最佳实践service+AlarmManager+Thread