需要APP暗屏情况下进行后台执行一些任务,但是google现在为了优化手机的体验,以及流畅性,做了很多的限制,电量优化,休眠模式,以及进入深度睡眠状态,进入深入休眠状态系统会根据黑白名单的应用进行管理,杀掉非白名单的后台进程以及网络请求;Android系统的优化是守护后台进程造成了很大困扰,线程之间守护已经是不在可靠,使用wakelock耗电过大也会是系统杀掉应用进程。下面就对我们的经历说说守护进程的。
1,从官网上可以看出google为了系统更加流畅以及优化内存,Google做了很大的处理,在手机暗屏或者睡眠状态就停止后台运行;若要保持service的常驻,需要做一些前端的活动,Notification重要属性:notification.flags = Notification.FLAG_NO_CLEAR|Notification.FLAG_ONGOING_EVENT;然后startForeground(setClass().hashCode(), notification);使得服务能挂在通知栏。
2,通过wakelock占用CPU,若一直占用CPU的话,当然这是比较耗电的,要是耗电太高的话系统会直接回收,杀死程序进程。
我是使用定时器唤醒cpu 后台服务将接收到定时任务执行未完成的任务:下面是我实现的代码
在mainfest中注册
关键代码定时任务:
1publicvoidstartAlarm(Context context){ 2Intent intent =newIntent(context, WakeCPUAlarmReceiver.class); 3alarmIntent = PendingIntent.getBroadcast(context,0, intent,0); 4alarmMgr = (AlarmManager) context .getSystemService(Context.ALARM_SERVICE);// alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,// 1000, alarmIntent); 5if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 6 alarmMgr.setExactAndAllowWhileIdle( 7 AlarmManager.ELAPSED_REALTIME_WAKEUP, 8 SystemClock.elapsedRealtime() + chekcTime, alarmIntent); 9 }else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 10 alarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + chekcTime, alarmIntent); 11 }else{ 12 alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 13 SystemClock.elapsedRealtime() + chekcTime, alarmIntent); 14 } 15 FileLogUtil.e(TAG ,"startAlarm 设置定时任务"); }
接收到定时任务:
1publicclassWakeCPUAlarmReceiverextendsWakefulBroadcastReceiver{ 2privateAlarmManageralarmMgr; 3privatePendingIntentalarmIntent; 4privatefinallong chekcTime =30*1000; 5public static boolean isCheckFlag =false; 6privatestaticStringTAG=WakeCPUAlarmReceiver.class.getSimpleName(); 7@Override 8public void onReceive(Contextcontext,Intentintent) { 9// TODO Auto-generated method stub 10Intentservice =newIntent(context,WakecpuIntentService.class); 11FileLogUtil.e(TAG,"onReceive 接收定时任务"); 12startWakefulService(context, service); 13} 14 15
在service中执行需要执行的任务:
1public class WakecpuIntentService extends IntentService{ 2private static String TAG=WakecpuIntentService.class.getSimpleName() +" :"; 3private NotificationManager mNotificationManager; 4private PowerManager.WakeLockwl; 5NotificationCompat.Builderbuilder; 6public WakecpuIntentService() { 7super("WakecpuIntentService"); 8// TODO Auto-generated constructor stub 9} 10@Override 11protected void onHandleIntent(Intentintent) { 12// TODO Auto-generated method stubBundle 13extras = intent.getExtras(); 14FileLogUtil.e(TAG,"Service接收到WakeLock定时任务。"); 15PollService.startService(getApplicationContext()); 16FileLogUtil.e(TAG,"Service接收到WakeLock定时任务在定时任务中启动轮询Service。"); 17// Do the work that requires your app to keep the CPU running. 18// Release the wake lock provided by the WakefulBroadcastReceiver. 19//checkScreenOff(); 20WakeCPUAlarmReceiver.completeWakefulIntent(intent);//释放wake 21WakeCPUAlarmReceiver.setCheckFlag(false); 22WakeCPUAlarmReceivermAlarmReceiver =newWakeCPUAlarmReceiver(); 23mAlarmReceiver.startAlarm(WakecpuIntentService.this); 24FileLogUtil.e(TAG,"Service释放wakelock后设置定时任务。"); 25 } 26}
service在后台也能够打印log 保持一直执行,最重要的是不耗电也不会卡机的问题。欢迎大家一起讨论学习。
关注公众号获取更多干货
