Android 开发---对非SDK接口限制的适配

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34902522/article/details/83791983

前言

项目升级到Android Pie(9),需要考虑适配问题.在此做个总结.
Android 9 增加了对非SDK接口访问的限制,无论你是直接访问还是通过反射,JNI等间接访问,都是会被限制的.


SDK接口和非SDK接口有啥区别?

SDK接口是那些官方支持的,Android framework 文档中可以找的.Android framework Package index .那非SDK接口就自然是相反的意思了.


非SDK接口的级别

非SDK接口很对,Google对它按限制程度进行了分类,分为light-greylist(浅灰列表),dark-greylist(深灰列表),blacklist(黑列表). 颜色的加深,限制程度也是随之加深.

  1. 对于light-greylist,非SDK接口的Methods/fields 还可以继续使用
  2. 对于dark-greylist,应用的target SDK version 小于28的,非SDK接口还是可以继续使用的,但是如果target Sdk version 大于等于28的话,就不能用了,会抛exception 如:NoSuchMethodError/NoSuchFieldException.
  3. 对于blacklist 无论你的target SDK version 是多少,都不能用非SDK接口.否则就会出现异常.

注意
对于light-greylist和dark-greylist,他们都属于grey,灰色的,虽然现在在Android 9上还可以使用,但是在之后的版本中,不能保证还可不可以继续用,没准,现在在grey list里的下个版本就被Google移到 black list列表里面了

继续使用非SDK接口导致的结果

上面其实说的也比较清楚了,就是出现异常.下面的表也描述的更具体点

访问方式 结果
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接口列表

上面说说了,有三种非SDK接口列表,如果我们想知道这些列表里面的具体有哪些内容,可以进入Google提供的列表索引里去查看,看看具体是哪些限制的method,field.

  1. 浅灰列表(light-greylist)
  2. 深灰列表(dark-greylist)
  3. 黑列表(blacklist)

定位非SDK接口

  1. 你可以在Android 9的设备上面运行你的app,如果你的APP有访问非SDK接口的话,会打印出相关的log信息,来帮助你定位,解决非SDK接口问题.log的信息样式如下:
    Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

  2. Android 9 支持通过使用StrictMode的相应Api来检测非SDK接口的使用.通过使用detectNonSdkApiUsage 方法来启用检测功能,检测功能的启用越早启用越好,官方建议是在application的onCreate方法中调用.关于使用这个方法来检测非SDK接口的调用,大家可以自行去源码中看该方法的使用,有注释说明,很容易上手,在此就不再赘述.

  3. 通过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

展开阅读全文

没有更多推荐了,返回首页