登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

Android 适配总结之服务 [复制链接]

2019-3-15 11:07
BeatBeat 阅读:320 评论:0 赞:0
Tag:  

1 参考

  • Android 8.0 + Service开启方式兼容处理
  • 后台执行限制

2 变更记录

2.1 Android 8.0 后台执行限制

手机同时运行的应用越多,对系统造成的负担越大。 如果还有应用或服务在后台运行,这会对系统造成更大负担,进而可能导致用户体验下降;例如,音乐应用可能会突然关闭。

为了降低发生这些问题的几率,Android 8.0 对应用在用户不与其直接交互时可以执行的操作施加了限制。

应用在两个方面受到限制:

后台服务限制:处于空闲状态时,应用可以使用的后台服务存在限制。 这些限制不适用于前台服务,因为前台服务更容易引起用户注意。

广播限制:除了有限的例外情况,应用无法使用清单注册隐式广播。 它们仍然可以在运行时注册这些广播,并且可以使用清单注册专门针对它们的显式广播。

注:默认情况下,这些限制仅适用于针对 O 的应用。 不过,用户可以从 Settings 屏幕为任意应用启用这些限制,即使应用并不是以 O 为目标平台。

在大多数情况下,应用都可以使用 JobScheduler 作业克服这些限制。 这种方式让应用安排为在未活跃运行时执行工作,不过仍能够使系统可以在不影响用户体验的情况下安排这些作业。

评价一下,JobScheduler最大的缺点是不支持Android5.0以下版本,如果你想使你的应用兼容至Android.4.4,还是得老老实实用Service。所以到现在我还没用过JobScheduler。。。

Android 8.0 对特定函数做出了以下变更:

  • 如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。
  • 新的 Context.startForegroundService() 函数将启动一个前台服务。现在,即使应用在后台运行,系统也允许其调用 Context.startForegroundService()。不过,应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。同时,调用startForeground()需要传入一个通知notification,注意notification也要适配Android8.0。

2.2 Android 9.0 前台服务

针对 Android 9 或更高版本并使用前台服务的应用必须请求 FOREGROUND_SERVICE 权限。这是普通权限,因此,系统会自动为请求权限的应用授予此权限。 如果针对 Android 9 或更高版本的应用尝试创建一个前台服务且未请求 FOREGROUND_SERVICE,则系统会引发 SecurityException。

2.3 解决方案

本方案的目的是使应用的服务在锁屏后不被销毁,比如我最近做了集成mqtt的项目,mqtt本质是个长连接,随时都得接收和发送mqtt消息,所以mqtt最好是待在一个不容易被销毁的Service上。

1 适配启动服务代码

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
// Android 8.0 改为前台服务方式启动
context.startForegroundService(intent);
} else {
context.startService(intent);
}

2 系统说明在调用 context.startForegroundService(intent)后5s内需要调用service.startForeground()

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
// 注意notification也要适配Android 8 哦
...
startForeground(1, notification);
}

这里要说下,startForeground()方法的第一个参数不能为0,即使调用了,也是启动服务后5s程序崩溃,异常说你没有在5s内调startForeground(),也不知道什么原因,反正为0就是会出错。

谷歌官方就是希望你应用的常驻服务在运行时能让用户看见,然后用户可以选择关闭服务。。我们开发者或者产品肯定是不希望让用户看到的,较敏感的用户可能看到这个通知立马就给你屏蔽了,让你服务都启动不了。

小米手机MIUI10效果就像这样:

Android 适配总结之服务

前台服务

刚开始startForeground(0, notification),通知是没有显示的,但是出现了没调startForeground()的崩溃问题。

应用业务就是需要常驻服务,暂时就用这样方案了。

为什么QQ,微信的常驻服务没有显示通知,我猜想的方案是有一个定时任务不断的启动服务,保证它不会被kill掉,其它方案就可能是些黑科技了。

停止服务时

要加上这个:

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
stopForeground(true);// 只是移除通知,没有停止服务的功能
}

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(0)

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

返回顶部