Android-Q 对 startActivity() 做了限制,怎么适配?

一. Q 禁用后台启动 Activity

今天来聊聊"Android Q 中后台禁止启动 Activity 对现有国内 App 中启动页设计的影响"这个话题,再聊聊 Android Q 限制后台启动 Activity 的具体细节。

有人可能会觉得 P 还没用上,Q 还远着。如果只是对于普通用户来说,确实是这样,大多数情况新系统对应的就是新设备,手机的换代速度是远低于系统升级的。但是对于我们开发者来说,老旧的系统版本可以战略性的放弃,但是新系统肯定要率先支持的。

就算你不想这么做,各大硬件厂商,也会推动你去做,毕竟最新的设备都是搭载的最新的系统,App 不稳定,肯定是影响用户体验的。

Android Q 在今年 Q3 季度,就准备发布正式版了,了解 Android Q 的新特性,也是我们开发者马上马就要面临的事情了。

言归正传,继续聊 Android Q 下,禁止后台启动 Activity。

二. 限制影响的范围

以最新的 Android Q Beta 4 来举例,当你的 App 处于后台时,一旦尝试开启新的页面,会发生什么呢?首先你的新页面肯定是打不开的,在现有的 Beta 版本上,系统还会输出一条警告 Log,并弹出一条 Toast。

例如,我们开发者比较常用的 掘金App。

官方文档表示,Toast 提醒会在 Android Q 的正式版中去掉。同时这里的没打开是真的没打开,它并不会压入到 Activity 的回退栈中。

Android Q 中针对启动 Activity 的限制,更多的也是为了增加用户体验和安全性。多数时候,我们开启新页面的动作,都来自用户操作,但是依然存在一些 App,在后台活着,监听用户的一些事件,在他们觉得必要的时机,弹出来骚扰用户。

比较常见的场景,你正在拍摄某个重要的瞬间,此时突然从后台弹出一个广告,精彩瞬间肯定是错过了,这必然会影响用户体验。

再比如一些工具类 App,会在某些事件上对你做出提醒,例如某浏览器就监听了卸载 App 的事件,在我卸载 App 后,提醒是否需要清理手机内存。

这些其实都是工具类 App 功能上的扩展,在 Android Q 下,这将是不被允许的。

在曾经那么多 Android 版本的适配中,很多新系统的特性,其实是有兼容模式的,只要保持 App 的 targetVersion 不升级,就不会触发新系统特性。

但是这一点,在 Android Q 的禁止后台启动页面这一项上,是不起作用的。此项变动适用于所有在 Android Q 上运行的应用,哪怕你没有升级 targetVersion,哪怕你是在 Android P(9)中安装应用,系统从就版本升级到 Android Q,此项改动都会生效。

只要跑在 Android Q 上的 App,均受限制。

原则上,只要你的 App 在前台,或者此次启动新页面的动作来自用户主动的操作,那自然是不受影响的。

1. 该应用具有可见窗口。例如前台 Activity 是你的应用。

2. 桌面 Widget 点击启动 Activity。

3. 当前前台任务的 Activity Back Task(回退栈)中,有你应用的 Activity。

例如调起微信支付页(Activity Z)时,当前退回栈最顶端的 Activity 其实时微信的页面,但是我们应用页面(Activity Y)依然在回退栈的下面,此时依然具有打开 Activity 的权限。

4. 绑定了某些系统服务,例如:AccessibilityService、AutofillService 等。

5. 已获得用户授权的 SYSTEM_ALERT_WINDOW 权限。

6. 临时白名单机制,不拦截通过通知拉起的应用。

  • 应用通过通知,在 pendingIntent 中启动 Activity。
  • 应用通过通知,在 PendingIntent 中发送广播,接收广播后启动 Activity。
  • 应用通过通知,在 PendingIntent 中启动 Service,在 Service 中启动 Activity。

还有一些比较特殊的场景,就不在这里一一举例了,有兴趣可以翻阅文档。

现在允许的这些条件,在 Android Q 正式版发布时,可能还有调整。例如拥有SYSTEM_ALERT_WINDOW 权限可以在后台打开新页这一条,在最初的 Beta1 版本中,是不存在的。

最终肯定是以 Android Q 正式版为准,我们只需要记住,原则上,只要是用户主动的操作或者用户赋予了相应的权限之外,其他情况均会受到影响。

三. 谷歌的适配建议

Android Q 禁用后台启动新页,不是目的,根本问题是为了加强用户体验。在某些场景下,我们也确实有在后台时,弹出新页的需求。

例如:收到微信语音通话时,对用户的强提醒。

总是有一些正当的需求,谷歌也不能直接把路都堵死了。

谷歌的建议是,在后台时,可以通过创建通知的方式,向用户提供信息。由用户通过点击通知的方式,来启动 Activity,而不是直接启动。

如果有必要,还可以通过 setFullScreenIntent() 来强调这是一个立即需要处理的通知。

kotlin 复制代码
val fullScreenIntent = Intent(this, BackgroundActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(
  this, 0,
  fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
​
val notificationBuilder = NotificationCompat.Builder(this, "channelId")
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(getString(R.string.app_name))
.setContentText("启动BackgroundActivity")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
​
// Use a full-screen intent only for the highest-priority alerts where you
// have an associated activity that you would like to launch after the user
// interacts with the notification. Also, if your app targets Android Q, you
// need to request the USE_FULL_SCREEN_INTENT permission in order for the
// platform to invoke this notification.
.setFullScreenIntent(fullScreenPendingIntent, true)
​
val incomingCallNotification = notificationBuilder.build()
​
// The integer ID that you give to startForeground() must not be 0.
startForeground(1, incomingCallNotification)

此时通知栏就会收到你给的通知,等待用户来处理。

利用通知来提醒用户,其实也有一些优势,例如不会打扰用户当前的行为,锁屏时依然可以提醒用户等等。

利用通知,其实只是我们的应用在后台时的一种替代方案,我们只需要根据不同的场景,在前台时打开新页,在后台时,使用通知提醒。

具体如何判断当前 App 时否在前台,可以利用registerActivityLifecycleCallbacks() 方法,对所有页面的生命周期进行监控,以此为依据来确定具体逻辑。

从 Beta2 开始,此限制是默认开启的,可以通过开发者选项 → 『允许后台活动启动』选项来控制其功能的开启和关闭。

四. 小结时刻

Android Q 下,限制后台启动页面的具体细节就到这里了,简单小结一下。

  1. Android Q 下,开始限制后台应用启动新页面,并且影响所有应用。
  2. 有一些例外场景,原则上为用户触发或者获得用户授权的情况下,依然可以打开新页,这时不受影响的。
  3. 在后台时,依然想为用户提供服务,可以借助通知(Notification)提醒用户。

最后

更多Android进阶指南 可以详细Vx关注公众号:Android老皮 解锁 《Android十大板块文档》

1.Android车载应用开发系统学习指南(附项目实战)

2.Android Framework学习指南,助力成为系统级开发高手

3.2023最新Android中高级面试题汇总+解析,告别零offer

4.企业级Android音视频开发学习路线+项目实战(附源码)

5.Android Jetpack从入门到精通,构建高质量UI界面

6.Flutter技术解析与实战,跨平台首要之选

7.Kotlin从入门到实战,全方面提升架构基础

8.高级Android插件化与组件化(含实战教程和源码)

9.Android 性能优化实战+360°全方面性能调优

10.Android零基础入门到精通,高手进阶之路

敲代码不易,关注一下吧。ღ( ´・ᴗ・` ) 🤔

相关推荐
肖哥弹架构1 天前
Spring 全家桶使用教程
java·后端·程序员
IT杨秀才4 天前
自己动手写了一个协程池
后端·程序员·go
程序员麻辣烫6 天前
像AI一样思考
程序员
一颗苹果OMG7 天前
关于进游戏公司实习的第一周
前端·程序员
万少8 天前
你会了吗 HarmonyOS Next 项目级别的注释规范
前端·程序员·harmonyos
楽码8 天前
彻底理解时间?在编程中使用原子钟
后端·算法·程序员
江南一点雨9 天前
又一家培训机构即将倒闭!打工人讨薪无果,想报名的小伙伴擦亮眼睛~
java·程序员
用户86178277365189 天前
ELK 搭建 & 日志集成
java·后端·程序员
河北小田9 天前
局部变量成员变量、引用类型、this、static
java·后端·程序员
文心快码 Baidu Comate9 天前
新一代的程序员如何培养自己的核心竞争力?(一)
人工智能·程序员·ai编程·文心快码·智能编程助手