一.背景
1.非 SDK 接口限制
非SDK接口限制在Android P中就已提出,但是在Q中,被限制的接口的分类有较大变化。
2.非SDK接口介绍
为了确保应用稳定性和兼容性,Android 平台开始限制您的应用可在 Android 9(API 级别 28)中使用哪些非 SDK 接口。Android Q包含更新后的受限非 SDK 接口列表(基于Android 开发者之间的协作以及最新的内部测试)。
非SDK接口限制就是某些SDK中的私用方法,如private方法,你通过Java反射等方法获取并调用了。那么这些调用将在target>=P或target>=Q的设备上被限制使用,当你使用了这些方法后,会报错:
非SDK接口查找
如果您不确定自己的应用是否使用了非 SDK 接口,则可以测试该应用进行确认。
当你调用了非SDK接口时,会有类似Accessing hidden XXX的日志:
Accessing hidden field Landroid/os/Message;->flags:I(light greylist,JNI)
但是一个大项目到底哪里使用了这些方法,靠review代码和看日志肯定是不现实的,谷歌官方也提供了官方检查器veridex用来检测一个apk中哪里使用了非SDK接口。也就是本次要介绍的veridex的使用
二.veridex的下载
1.官网下载地址:veridex
2.官网下载需要梯子,这里提供百度云下载地址,如果链接失效,请在下发评论区留言
百度网盘下载地址 提取码:2tow
由于veridex现在没有window的版本,所以我们只能window系统的只能自己下载Linux系统进行使用,下面介绍window 1-安装Linux子系统 ubuntu
三.Windows10安装Linux子系统Ubuntu
1、开启开发者模式
顺序:打开 系统设置 --- 更新和安全 --- 针对开发人员---选择开发者模式
点击后会自动安装环境
2、安装 Windows 10 的 Linux 子系统组件
顺序: 打开 系统设置 --- 应用 --- 右侧的程序和功能 --- 启动或关闭windows功能 ---勾选适用于 Linux 的 Windows 子系统
确定后,重启电脑,系统更新配置
3、安装 Linux 子系统
打开 Windows 应用市场,输入 linux 搜索,选择你自己想要的系统版本,我选择的是 Ubuntu ,然后下载安装,微软的下载速度还是挺快的,很快就下载完了。
然后点击启动,第一次会进行初始化安装。
安装时注意 Win10 有个存在好久一直没修复很烦人的 BUG ,就是 CMD 总是会遇到不会自动刷新输出内容卡在那儿不动,一直显示安装中,实际初始化是很快的,按下回车键发现已经安装好了只是没输出而已。
初始化安装完成,现在设置帐号密码,就搞定了
参考文档:Windows10安装Linux子系统Ubuntu
四.veridex的使用
下载好veridex后解压文件,选择veridex-linux文件解压,并打开Ubuntu进入到该文件夹目录,选择要检测的安装包apk文件复制到相同文件夹目录下,然后使用下面的命令执行(test.apk为你的apk文件名):
./appcompat.sh --dex-file=test.apk
扫描结果分为两部分,一部分为被调用的非SDK接口的位置,另一部分为非SDK接口数量统计:
1.greylist: 灰名单,即当前版本仍能使用的非SDK接口,但在下一版本中可能变成被限制的非SDK接口
2.blacklist:黑名单,使用了就会报错。也是我们项目中必须解决的非SDK接口
3.greylist-max-o:在targetSDK<=O中能使用,但是在targetSDK>=P中被限制的非SDK接口
4.greylist-max-p:在targetSDK<=P中能使用,但是在targetSDK>=Q中被限制的非SDK接口
所以从适配Q的角度出发,除了greylist我们可以暂时不解决以外,其余三种类型的非SDK接口需要我们进行适配。
五.非SDK接口适配
如果您的应用依赖于非 SDK 接口,则应该开始计划迁移到 SDK 替代方案。如果您无法为应用中的某项功能找到使用非 SDK 接口的替代方案,则应该请求新的公共 API。
官方要求targetSDK>=P的应用不使用这些方法,并寻找其他的公共API去替代这些非SDK接口,如果找不到,则可以向谷歌申请,请求一个新的公共API https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces#feature-request (一般不需要)。
项目中使用非SDK接口大概率有以下两种情况:
1.在自定义View的过程中为了方便,使用反射修改某个参数。
2.三方SDK中使用了非SDK接口(这种情况比较多)。
第一种是好解决的,毕竟是我们自己写的代码。
第二种就头疼了,只能更新到最新的三方SDK版本,或者提工单、换库(也是整个适配过程中工作量最庞大的部分)。