为了账号安全,请及时绑定邮箱和手机立即绑定

Android适配总结之服务

标签:
Android

 变更记录

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效果就像这样:

webp

前台服务


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

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

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

停止服务时

要加上这个:

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



作者:newtrek
链接:https://www.jianshu.com/p/ae3d654ce3b6


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消