应用不兼容的常见原因
Android M 就已经开始移除对 Apache HTTP client 的支持。而 Android P 的系统 ClassLoader 已经不支持加载 org.apache.http.*包 (抛出 NoClassDefFoundError),应用必须用自定义的 ClassLoader 来加载,同时确保 org.apache.http.* 的路径包含在应用 classpath 上。
应用不应该再使用 org.apache.http.legacy 库,如果实在必须,可以将它打包进自己的 APK,同时改名以防止与运行时的版本冲突。
没有使用兼容 Android 9 的加固服务
直接调用 dex2oat
从一开始,dex2oat 就被设计为系统内部使用的编译部署工具,Android 从来都未支持过开发者直接调用 dex2oat 的场景。
如果您需要从内存中加载 dex 文件,而不愿在存储中留下痕迹,请使用 Android O 中新增的加载器 InMemoryDexClassLoader。
相关的 dex / so 文件亦不应直接操作或篡改,干扰或篡改系统内部加载 dex 的逻辑很可能会导致兼容性问题。
使用了非 SDK 接口
非 SDK 接口在每次版本更新中都有可能被改动,开发者应只使用 SDK 接口。
使用了不兼容的第三方的库
如果您使用的第三方库尚不支持 Android P 版本,请报告给其提供商,帮助推动它解决兼容性问题。
非 SDK 接口的限制名单
- 白名单
- Android SDK 本身
- 没有任何限制
- 黑名单
- 只能被 Android 系统及系统应用使用
- 无论 targetSdkVersion 都禁止使用
- 对应用开发者来说,相当于没有这些接口
- 深灰名单
- 没有发现应用在使用,但我们觉得有潜在的可能性
- 当 targetSdkVersion < P 时允许使用
- 当 targetSdkVersion >= P 时禁止使用 (相当于黑名单)
- 浅灰名单
- 已有应用在使用的非 SDK 接口,仍然可以继续使用
- 将来会考虑提供相应的 SDK 接口
- 当 targetSdkVersion >= P 时系统提示警告
凹口屏幕 Display Cutout
- 不要硬编码状态栏的高度,请使用 WindowInsetsCompat 获取状态列的高度。
- 注意屏幕大小与显示范围的差异,请使用 View.getLocationInWindow(),而不是 View.getLocationOnScreen()。处理 MotionEvent 时,使用 getX() / getY() ,而不是 getRawX() / getRawY() 。
- 凹口可以置中或靠边,只会在屏幕短边出现,两条短边皆可有缺口。
屏幕旋转锁定
Inline 函数调用检查
空闲应用无法访问麦克风、摄像头和传感器
前台服务权限
后台服务限制
Google Play targetSdkVersion 政策
- 从 2018 年 8 月起,新发布的应用必须将 targetSdkVersion 设置为 26 或更高
- 从 2018 年 11 月起,现有应用的升级必须将 targetSdkVersion 设置为 26 或更高
- 2019 年之后,新发布或升级应用必须将 targetSdkVersion 设置为一年内发布的 Android 版本