项目升级到Android Pie(9),需要考虑适配问题.在此做个总结.
Android 9 增加了对非SDK接口访问的限制,无论你是直接访问还是通过反射,JNI等间接访问,都是会被限制的.
SDK接口是那些官方支持的,Android framework 文档中可以找的.Android framework Package index .那非SDK接口就自然是相反的意思了.
非SDK接口很对,Google对它按限制程度进行了分类,分为light-greylist(浅灰列表),dark-greylist(深灰列表),blacklist(黑列表). 颜色的加深,限制程度也是随之加深.
注意
对于light-greylist和dark-greylist,他们都属于grey,灰色的,虽然现在在Android 9上还可以使用,但是在之后的版本中,不能保证还可不可以继续用,没准,现在在grey list里的下个版本就被Google移到 black list列表里面了
上面其实说的也比较清楚了,就是出现异常.下面的表也描述的更具体点
访问方式 | 结果 |
---|---|
Dalvik指令 引用一个field | NoSuchFieldError thrown |
Dalvik指令 引用一个method | NoSuchMethodError thrown |
通过Class.getDeclaredField() or Class.getField()反射 | NoSuchFieldException thrown,Non-SDK members not in results |
通过Class.getDeclaredMethod(), Class.getMethod()反射 | NoSuchMethodException thrown,Non-SDK members not in results |
JNI 通过 env->GetFieldID()方式 | NULL returned, NoSuchFieldError thrown |
JNI 通过 env->GetMethodID()方式 | NULL returned, NoSuchMethodError thrown |
上面说说了,有三种非SDK接口列表,如果我们想知道这些列表里面的具体有哪些内容,可以进入Google提供的列表索引里去查看,看看具体是哪些限制的method,field.
你可以在Android 9的设备上面运行你的app,如果你的APP有访问非SDK接口的话,会打印出相关的log信息,来帮助你定位,解决非SDK接口问题.log的信息样式如下:
Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
Android 9 支持通过使用StrictMode的相应Api来检测非SDK接口的使用.通过使用detectNonSdkApiUsage 方法来启用检测功能,检测功能的启用越早启用越好,官方建议是在application的onCreate方法中调用.关于使用这个方法来检测非SDK接口的调用,大家可以自行去源码中看该方法的使用,有注释说明,很容易上手,在此就不再赘述.
通过Google提供的检测分析工具veridex来,检测非SDK接口的使用情况.veridex的下载地址如下:
veridex download address
我的平台的是Linux的,所以把veridex-linux.zip 解压后,cd 进入,使用./appcompat.sh --dex-file = test.apk(apk file location) 命令即可完成检测.
效果如下:
从veridex下载列表上面只看到了适合Linux平台的,Mac平台的veridex压缩包,没看到Windows的,网上有看到说Windows平台的不能用这个工具,但是这边试了与veridex-linux.zip同级目录下的appcompat.sh脚本,发现也可以实现相同的检测效果.所以有点怀疑,但是没有Windows的设备来测试,如果有试过的可以把结果告知一下.
定位了解到项目中非SDK接口的使用情况后,就可以做出对应的调整,完成适配,避免crash.如果必须要用某种非SDK接口的话,可以向Google提出申请,请求地址如下:
https://issuetracker.google.com/issues/new?component=328403&template=1027267