Android 14适配总结
毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。
现在,第四个Android版本已经适配完,总结记录一下。
1、Android 14计划
Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以及开发者,宣讲主要有哪些方面的变化。
4~6月份则会发布Beta版本,这个阶段各个手机厂商开始抓紧适配中。8~9月份左右会发布稳定版本。不出意外,国内的手机厂商会在11~12月份开始推送Android新版本的升级。
2、获取Android 14
怎么知道有没有适配成功呢?最好的办法还是在Android 14的设备上运行一下。
2.1、创建Android 14虚拟机
在Android Studio中下载Android 14的系统镜像
创建Android 14虚拟机,运行调试。
2.2、Android 14预览版
在Google的push下,各个厂商都要求尽快适配,并且提供各自ROM基于Android 14的Beta预览版本。这些版本可以在设备制造商各自的网站上获取。
vivo :https://developer.vivo.com/promotion/android14
XIAOMI :https://www.mi.com/global/support/guidance/androidtbeta
OPPO :https://developers.oppomobile.com/wiki/doc/index#id=138
3、适配Android 14
并非所有的变更都需要修改适配,也是因应用而异,不涉及的当然跳过即可。完整的Android 14变更列表详见:Android 14 features and changes list。针对Android 14主要几点变更适配记录如下:
需要 AGP 7.0.0 或更高版本,使用Android 14对应的值:UpsideDownCake,更新build.gradle:
android {
compileSdkPreview = "UpsideDownCake"
...
defaultConfig {
targetSdkPreview = "UpsideDownCake"
}
}
这个应该是Android 14最大的一点变化,targetSdkVersion 低于 23 的应用将无法安装在Android 14设备上。是时候放弃一波老旧的代码了,Google此举可以减少一大部分旧代码的维护成本。
看了下手机里安装的120多款常用应用,只有极个别 targetSdkVersion 还在23以下,其它都在23以上,而且已经有应用率先完成适配,targetSdkVersion 已经是34了。
如果开发的应用targetSdkVersion还低于23,马上修改,不然应用就要被“淘汰”。
defaultConfig {
minSdk 24
//用户无法安装 targetSdkVersion 低于 23 的应用
targetSdk 33
}
对于以 Android 14 为目标平台的应用,Android 会通过以下方式限制应用向内部应用组件发送隐式 Intent:
- 隐式 intent 只能传送到导出的组件。应用必须使用显式 intent 传送到未导出的组件,或将该组件标记为已导出。
- 如果应用通过未指定组件或软件包的 intent 创建可变待处理 intent,系统现在会抛出异常。
开发者需要仔细检查一下自己项目的代码,是否创建创建类似的隐式Intent。平时开发应当都用显示Intent,避免使用隐式未定Intent。
广播接收器自Android 8.0以后改为动态注册,后来Android 12的时候组件必须显示指定是否exported导出。由于BroadcastReceiver是动态注册的,作为曾经的“四大组件”之一的广播接收器,是否exported导出这点没有明确。这个改动之前觉得挺迷惑。
这次Android 14适配明确了:凡以 Android 14 为目标平台并使用上下文注册的接收器的应用和服务必须指定以下标志,以指明接收器是否应导出到设备上的所有其他应用:RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED。
但是,Google又定了一个迷惑规定:如果您的应用仅通过 Context#registerReceiver()针对系统广播注册接收器,那么它在注册接收器时不应指定标志。这时候如果指定了标志反而会抛出异常。
到底哪些是系统广播?哪些不属于?各个ROM厂商定制的系统广播算不算?同时注册系统广播和非系统广播的接收器该怎么注册?因为系统广播没有一个明确的清单列表,如果在不需要指定标志的时候传入了标志,又或者需要标志的时候漏传了标志。这里埋了一个不明确的坑。
这点是Android 14上安全相关的整改:对于以 Android 14 为目标平台的应用,Android 会通过以下方式防止 Zip 路径遍历漏洞:如果 Zip 文件条目名称包含“..”或以“/”开头,ZipFile(String) 和 ZipInputStream.getNextEntry() 会抛出 ZipException。
如果不想报错,可以屏蔽这个特性:通过调用 dalvik.system.ZipPathValidator.clearCallback() 选择停用Zip遍历安全漏洞验证。
对于以 Android 14 为目标平台的应用,系统会进一步限制应用后台启动Activity。
比如,有从后台Service中启动拉起Activity界面的业务场景。务必注意:bindService() 方法绑定其他在后台应用的服务时,如果可见应用想要授予自己的后台 Activity 对绑定服务的启动特权,则必须选择启用。应在调用 bindService() 方法时包含 BIND_ALLOW_ACTIVITY_STARTS标志。
从 Android 14 开始,系统支持字体放大高达 200%,而且是非线性放缩。光是这一条修改,工作量直接爆表!
大多数应用当然可以选择不适配字体大小,让自己的应用字体不跟随系统设置变化(字体单位用dp,不用sp,或者锁定fontScale配置)。但是ROM应用、Google原生应用都是强制适配,犹记得去年字体大小适配(最大放缩到150%),应用绝大多数页面都是颠覆性的设计(从UI重新设计、开发),因为当初开发就完全没有考虑到页面缩放。
这一套适配下来,总结经验要领就一条:布局灵活自适应,让系统决定显示多大。人为干预越多,问题越多,只会无穷尽也。
Android 14开始支持Java 17语言,将build.gradle配置compileOptions改成JavaVersion.VERSION_17,以支持Java 17语法。
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
参考资料:
Android 14 Beta
Android 14 features and changes list