浅析Android——Android 8.0(O)后台服务的限制和变化

Android O对后台服务和隐式广播进行了限制,强制使用JobScheduler或前台服务创建。JobScheduler在满足特定约束时执行任务,以节省电量。文章详细介绍了JobScheduler的工作原理、应用场景、优势及使用流程,包括JobInfo、JobScheduler和JobService的交互,并提供了使用示例。适配Android O,开发者应充分利用JobScheduler来实现后台任务,确保良好的用户体验。
摘要由CSDN通过智能技术生成

Android 最近几版的特色主要集中在省电和后台管理上,O的发布,对Service和Broadcast又近一步加强了管束。主要可概括为如下两点:

      1、后台应用不被允许创建后台服务,必须通过JobScheduler或者Context.startForegroundService()进行创建

      2、特定的隐式广播不再被允许启动,必须通过JobScheduler调用或者显式注册的方式才能启动

      google之所以限制隐式广播,是因为广播的滥用导致设备在息屏等状态下,依然无法有效的做到省电,往往一个系统广播,会唤醒多个未启动的第三方应用。因此在O中,隐式广播的限制是很严厉的。谷歌给出了允许隐式注册的广播列表https://developer.android.com/preview/features/background-broadcasts.html,为了方便懒得上墙的小伙伴们,贴出整理的广播列表:

 
  1. 开机广播,之所以被允许,因为每次设备启动只会发送一次

  2. 1、ACTION_LOCKED_BOOT_COMPLETED(直接启动模式下才会发出)

  3. 2、ACTION_BOOT_COMPLETED

  4.  
  5. 以下三个广播有权限限制,一般应用无法接受。

  6. 3、ACTION_USER_INITIALIZE

  7. 4、android.intent.action.USER_ADDED

  8. 5、android.intent.action.USER_REMOVED

  9.  
  10. 地区变更广播,这个地区指的是国家一级,一般不会发送

  11. 6、ACTION_LOCALE_CHANGED

  12. 7、

  13. 时区闹钟变更相关的广播,一般时间类APP需要

  14. 7、ACTION_TIMEZONE_CHANGED

  15. 8、ACTION_NEXT_ALARM_CLOCK_CHANGED

  16. 9、android.intent.action.TIME_SET

  17.  
  18. usb事件广播,需要设备触发usb事件才能发送

  19. 10、ACTION_USB_ACCESSORY_ATTACHED

  20. 11、ACTION_USB_ACCESSORY_DETACHED

  21. 12、ACTION_USB_DEVICE_ATTACHED

  22. 13、ACTION_USB_DEVICE_DETACHED

  23.  
  24. 蓝牙事件广播,需要设备触发蓝牙事件才能发送

  25. 14、ACTION_CONNECTION_STATE_CHANGED

  26. 15、ACTION_ACL_CONNECTED

  27. 16、ACTION_ACL_DISCONNECTED

  28.  
  29. OEM相关的广播,一般是OEM通讯类应用会需要

  30. 17、ACTION_CARRIER_CONFIG_CHANGED

  31. 18、TelephoneyIntents.ACTION_*_SUBSCRIPTION_CHANGED

  32. 19、TelephoneyIntents.SECRET_CODE_ACTION

  33.  
  34. 登录用户状态发生改变时,这里指的是google登录,一般我们用不到,同时这个广播也在API26中废弃了。

  35. 20、LOGIN_ACCOUNTS_CHANGED_ACTION

  36.  
  37. 用户通过设置页面清除掉应用数据后才会发出

  38. 21、ACTION_PACKAGE_DATA_CLEARED

  39.  
  40. 来电广播

  41. 22、ACTION_NEW_OUTGOING_CALL

  42.  
  43. 设备隐私状态变更广播

  44. 23、ACTION_DEVICE_OWNER_CHANGED

  45.  
  46. 日历提醒广播,是由日历提供者发送给日历程序的

  47. 24、ACTION_EVENT_REMINDER

  48.  
  49. 程序卸载广播,跟程序卸载相关的广播中只有这个是被允许的。

  50. 25、ACTION_PACKAGE_FULLY_REMOVED

  51.  
  52. 设备媒体相关广播,但是一般会在开机时发出或者是在物理设备交互时发出。

  53. 26、ACTION_MEDIA_MOUNTED

  54. 27、ACTION_MEDIA_UNMOUNTABLE

  55. 28、ACTION_MEDIA_CHECKING

  56. 29、ACTION_MEDIA_UNMOUNTED

  57. 30、ACTION_MEDIA_EJECT

  58. 31、ACTION_MEDIA_REMOVED

  59. 32、ACTION_MEDIA_BAD_REMOVAL

  60.  
  61. 短信接收广播

  62. 33、SMS_RECEIVED_ACTION

  63. 34、WAP_PUSH_RECEIVED_ACTION

    可以概括的说,可以进行隐式注册的广播都是非频繁发送的,或者有着特定的触发场景的。google的目的就是杜绝一个广播唤醒多个后台应用这种现象。如果我们的应用中涉及到了列表以外的广播,就有必要进行O的适配了。

    google针对前台应用的定义,认为如果满足以下任意条件,应用将被视为处于前台:

   1、具有可见 Activity(不管该 Activity 已启动还是已暂停)。

   2、具有前台服务。

   3、另一个前台应用已关联到该应用(不管是通过绑定到其中一个服务,还是通过使用其中一个内容提供程序)。

  但在开发中,我们会更多的遇到后台运行的需求,当应用处于后台时,监听特定的系统广播或者设置守护Service显然不能很好的适应高版本,所以按照google的剧本走才是正道。以上两各变更点都提到了JobScheduler,JobScheduler作为API21新增类,如它的名字计划任务一样,通过设置约束条件,使系统可以在不影响用户体验的情况下安排这些作业执行。应用作业不会主动挤占系统运行时间,而是在约束范围下执行工作。Android也在不断地增加JobScheduler支持的约束条件,Oreo就新增了一个运行场景:

       1、NETWORK_TYPE_METERED 作业需要一个按流量计费的网络连接,比如大多数移动数据网络数据套餐。

新增了两个约束条件:

      1、JobInfo.isRequireStorageNotLow() 如果设备的可用存储空间非常低,作业将不会运行。

      2、JobInfo.isRequireBatteryNotLow() 如果电池电量等于或低于临界阈值,作业将不会运行;临界阈值是指设备显示 Low battery warning系统对话框的电量。

  当你需要持续的后台监听功能时,用守护Service或者监听特定的高频系统广播显然已经不合时宜了,google希望你通过JobSchedular来实现类似的功能。JobScheduler的运行实质是JobService,google对JobService的定义有这样一句话:This service executes each incoming job on a {@link android.os.Handler} running on your application's main thread.表明JobService是在主线程处理任务,也就是说当一个JobService处于onStartJob()时,应用进程实际是处于激活状态的,满足上文前台定义中的第二条:具有前台服务。而任务处理又是在系统许可范围内,可谓是皆大欢喜。同时JobService是继承自Service的,它的生命周期是:

onCreated()-->onStartJob-->onStopJob()-->jobFinished()-->onDestroy()

onCreated()继承自Service,google对onCreated的定义是这样的:Called by the system when the service is first created.  Do not call this method directly.即当前服务被创建时会调用一次,被创建意味着这个服务之前没有存在过或者被onDestroy了。

onStartJob()-->onStopJob()这个工作阶段取决于配置的约束条件,onStartJob()不会无限制的重复执行。如果我们不设定约束条件,那么JobService在创建成功后只会调用一次onStartJob。onDestroy()同样继承自Service的,google对onDestroy的定义有这样一句话:Called by the system to notify a Service that it is no longer used and is being removed.即当系统想要回收当前服务时,便会触发onDestroy,至于间隔多久会触发取决于系统当前操作。我们可以在onDestroy()中重新执行一次创建操作,即重新通知系统安排一次计划任务。保证我们的JobScheduler始终存在于系统任务调度队列中了,这样任务就会持续的运行下去,具体操作如下:

    (1)创建一个JobService命名为DetectionService,在onCreated()中显式注册一个BroadcastReceiver,用来接收应用自身的广播或者其他系统广播,作为唤醒JobService的辅助方式。(毕竟还有安全软件这种东西的存在)

 
  1. @Override

  2. public void onCreate() {

  3. super.onCreate();

  4. receiver = new AuxiliaryReceiver();

  5. IntentFilter intentFilter = new IntentFilter();

  6. intentFilter.addAction("your app's broadcasts");

  7. intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);

  8. registerReceiver(receiver, intentFilter);

  9. }

(2)在onDestroy()中执行重新创建当前JobService操作,不设定约束条件。

 
  1. @Override

  2. public void onDestroy() {

  3. super.onDestroy();

  4. unregisterReceiver(receiver);

  5. JobScheduler scheduler = null;

  6. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){

  7. scheduler = this.getSystemService(JobScheduler.class);

  8. }else{

  9. scheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE);

  10. }

  11. final JobInfo.Builder builder = new JobInfo.Builder(1024,new ComponentName(this, DetectionService.class));

  12. builder.setPersisted(true);

  13. builder.setOverrideDeadline(1000);

  14. scheduler.schedule(builder.build());

  15. }

(3)在onStartJob()中,你可以根据自己的需求安排具体操作。

  这种设计方式,可以实现类似Service常驻后台的效果,同时符合Android O中对后台运行的要求,但是会对省电模式有影响,如果你的APP没有这方面的顾虑话可以采取这种方式,如果有省电相关的需求,那就老老实实的只用JobScheduler启动一次。google通过JobScheduler规范后台应用启动的目的,就是为了保证设备的正常休眠和应用功耗的可控,我们在开发过程中更多的去遵守google标准,才能让用户有更好的产品体验。

 

JobScheduler应用场景

当你需要在Android设备满足某种场合才需要去执行处理数据,例如 
* 应用具有您可以推迟的非面向用户的工作(定期数据库数据更新) 
* 应用具有当插入设备时您希望优先执行的工作(充电时才希望执行的工作备份数据) 
* 需要访问网络或 Wi-Fi 连接的任务(如向服务器拉取内置数据) 
* 希望作为一个批次定期运行的许多任务

而使用JobScheduler可以很优雅的完成这些情况。

所以相比于其他方式,JobScheduler的好处是显而易见的。 
* 避免频繁的唤醒硬件模块,造成不必要的电量消耗。 
* 避免在不合适的时间(例如低电量情况下、弱网络或者移动网络情况下的)执行过多的任务消耗电量;

JobScheduler和Android 6.0出现的Doze都一样,总结来说就是限制应用频繁唤醒硬件,从而达到省电的效果。

You do not instantiate this class

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值