行为变化:以 Android 14 或更高版本为目标平台的应用
与早期版本一样,Android 14 包含可能会影响应用的行为更改。以下行为更改仅适用于以 Android 14 或更高版本为目标平台的应用。如果您的应用以 Android 14 或更高版本为目标平台,则应修改应用以正确支持这些行为(如适用)。
核心功能
需要前台服务类型
如果您的应用以 Android 14 为目标平台,则必须为应用中的每个前台服务指定至少一种前台服务类型。您应该选择代表应用用例的前台服务类型。系统期望具有特定类型的前台服务满足特定用例。
注意:Android 14 为运行状况和远程消息传递用例引入了前台服务类型。该系统还为短期服务、特殊用例和系统豁免保留了新类型。
如果应用中的用例未与任何这些类型相关联,强烈建议您迁移逻辑以使用 WorkManager 或 user-user-initiated data。
OpenJDK 17 更新
Android 14 继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致,包括库更新和面向应用和平台开发人员的 Java 17 语言支持。
其中一些更改可能会影响应用兼容性:
- 对正则表达式的更改:现在不允许使用无效的组引用来更紧密地遵循 OpenJDK 的语义。您可能会看到 java.util.regex.Matcher 类抛出
IllegalArgumentException
的新情况,因此请确保测试您的应用程序是否存在使用正则表达式的区域。若要在测试时启用或禁用此更改,请使用兼容性框架工具切换DISALLOW_INVALID_GROUP_REFERENCE
标志. - UUID 处理:java.util.UUID.fromString() 方法现在在验证输入参数时会执行更严格的检查,因此您可能会在反序列化期间看到
IllegalArgumentException
。若要在测试时启用或禁用此更改,请使用WorkManager切换ENABLE_STRICT_VALIDATION
标志. - ProGuard 问题:在某些情况下,如果您尝试使用 ProGuard 缩小、混淆和优化应用,则添加 java.lang.ClassValue 类会导致问题。问题源于 Kotlin 库,该库根据 Class.forName("java.lang.ClassValue") 是否返回类来更改运行时行为。如果您的应用是针对旧版本的运行时开发的,没有可用的 java.lang.ClassValue 类,则这些优化可能会从派生自 java.lang.ClassValue 的类中删除 computeValue 方法。.
安全
对隐式和挂起意向的限制
对于以 Android 14 为目标平台的应用,Android 会通过以下方式限制应用向内部应用组件发送隐式意图:
- 隐式意向仅传递到导出的组件。应用必须使用明确的意图来交付到未导出的组件,或将组件标记为已导出。
- 如果应用创建可变挂起的意向,其意图未指定组件或包,则系统现在会引发异常。
这些更改可防止恶意应用拦截供应用内部组件使用的隐式意图。
例如,下面是可以在应用的清单文件中声明的 Intent 过滤器:例如,下面是可以在应用的清单文件中声明的 Intent 过滤器:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
如果您的应用尝试使用隐式意图启动此活动,则会引发异常:
// Throws an exception when targeting Android 14.
context.startActivity(new Intent("com.example.action.APP_ACTION"));
要启动非导出活动,您的应用应改用显式 Intent:
// This makes the intent explicit.
Intent explicitIntent =
new Intent("com.example.action.APP_ACTION")
explicitIntent.setPackage(context.getPackageName());
context.startActivity(explicitIntent);
运行时注册的广播接收器必须指定导出行为
以 Android 14 为目标平台并使用上下文注册接收器的应用和服务需要指定一个标志,以指示是否应将接收器导出到设备上的所有其他应用:RECEIVER_EXPORTED或RECEIVER_NOT_EXPORTED。此要求通过利用 Android 13 中引入的这些接收器的功能来帮助保护应用免受安全漏洞的影响.
仅接收系统广播的接收器的例外情况
如果你的应用仅通过 Context#registerReceiver 方法(如 Context#registerReceiver()为系统广播注册接收器,则在注册接收器时不应指定标志。Context#registerReceiver
更安全的动态代码加载
如果您的应用以 Android 14 为目标平台并使用动态代码加载 (DCL),则必须将所有动态加载的文件标记为只读。否则,系统将引发异常。我们建议应用尽可能避免动态加载代码,因为这样做会大大增加应用因代码注入或代码篡改而受到损害的风险。
如果必须动态加载代码,请使用以下方法在打开文件后和写入任何内容之前将动态加载的文件(如 DEX、JAR 或 APK 文件)设置为只读:
File jar = new File("DYNAMICALLY_LOADED_FILE.jar");
try (FileOutputStream os = new FileOutputStream(jar)) {
// Set the file to read-only first to prevent race conditions
jar.setReadOnly();
// Then write the actual file content
} catch (IOException e) { ... }
PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
处理已存在的动态加载文件
为了防止为现有的动态加载文件引发异常,我们建议先删除并重新创建这些文件,然后再尝试在应用中再次动态加载这些文件。重新创建文件时,请按照前面的指南在写入时将文件标记为只读。或者,你可以将现有文件重新标记为只读,但在这种情况下,我们强烈建议你先验证文件的完整性(例如,根据受信任的值检查文件的签名),以帮助保护你的应用免受恶意操作的侵害。
Zip path traversal
对于面向 Android 14 的应用,Android 通过以下方式防止 Zip 路径遍历漏洞:如果 zip 文件条目名称包含“..”或以“/”开头,则 ZipFile(String)) 和 ZipInputStream.getNextEntry() 会引发 ZipException。
应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback() 来选择退出此验证.
从后台启动活动的其他限制
对于以 Android 14 为目标平台的应用,系统会进一步限制何时允许应用从后台启动活动:
- 当应用使用 PendingIntent#send() 或类似方法发送 PendingIntent 时,如果应用想要授予自己的后台活动启动权限以启动挂起的 Intent,则应用现在必须选择加入。要选择加入,应用应传递带有setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED) 的 ActivityOptions 捆绑包.
- 当可见应用使用 bindService() 方法绑定后台的另一个应用的服务时,如果可见应用想要向绑定服务授予自己的后台活动启动权限,则它现在必须选择加入。若要选择加入,应用应在调用 bindService() 方法时包含 BIND_ALLOW_ACTIVITY_STARTS 标志。
这些更改扩展了现有的一组限制,通过防止恶意应用滥用 API 从后台启动破坏性活动来保护用户。
更新了非 SDK 限制
Android 14 包含基于与 Android 开发者合作和最新内部测试的受限非 SDK 接口的更新列表。在限制非 SDK 接口之前,我们会尽可能确保公共替代方案可用。
如果您的应用未定位到 Android 14,则其中一些更改可能不会立即对您产生影响。但是,虽然您目前可以使用某些非 SDK 接口(具体取决于应用的目标 API 级别),但使用任何非 SDK 方法或字段始终存在破坏应用的高风险。
如果您不确定您的应用是否使用非 SDK 接口,可以测试您的应用以了解。如果您的应用依赖于非 SDK 接口,则应开始计划迁移到 SDK 替代方案。不过,我们理解某些应用具有使用非 SDK 接口的有效用例。如果您找不到对应用中的功能使用非 SDK 接口的替代方法,则应请求新的公共 API.
要详细了解此版本的 Android 中的更改,请参阅 Android 14 中非 SDK 接口限制的更新。要了解有关非 SDK 接口的更多信息,请参阅对非 SDK 接口的限制.