Android P阻止调用非sdk api后,Atlas的影响及适配

自从Android P/9.0后,Android就已经开始着手阻止App开发调用非sdk的api,也就是被标记为@hide的变量、函数、类不可以通过反射调用,否则会提示NoSuchMethod异常

对Atlas影响

Atlas有许多调用都是通过反射系统api来完成的,其中不乏被标记为@hide的类,比如用来处理插件资源的android.content.res.AssetManager#addAssetPath,还有用来处理动态部署的启动新Activity的android.app.ActivityThread

/**
 * Add an additional set of assets to the asset manager.  This can be
 * either a directory or ZIP file.  Not for use by applications.  Returns
 * the cookie of the added asset, or 0 on failure.
 * {@hide}  WARM,该方法被标记为隐藏
 */
public final int addAssetPath(String path) {
    synchronized (this) {
        int res = addAssetPathNative(path);
        makeStringBlocks(mStringBlocks);
        return res;
    }
}
/**
 * This manages the execution of the main thread in an
 * application process, scheduling and executing activities,
 * broadcasts, and other operations on it as the activity
 * manager requests.
 *
 * {@hide}   高能,整个类都标记为隐藏
 */
public final class ActivityThread {

如果android.content.res.AssetManager#addAssetPath不能使用,资源在插件中就无法使用,如果android.app.ActivityThread整个类不让反射,那动态部署中无法添加新的Activity、Service

Android P 处理非sdk调用

但情况并没有想象的糟糕,Android P 阻止调用非sdk并不是绝对的,并不是标记了hide就一定会抛异常。还有个X因素——light-greylist,如果被hide的api在里面列出,就允许被反射调用。该列表如下:

https://github.com/aosp-mirror/platform_frameworks_base/blob/master/config/hiddenapi-p-light-greylist.txt

https://github.com/aosp-mirror/platform_frameworks_base/blob/master/config/hiddenapi-light-greylist.txt

乍一看addAssetPath和ActivityThread都在里面,看来Atlas还是有希望的,不过Atlas用的反射有许多,可以在Android P模拟器上运行下Atlas Demo试一试

Atlas的适配

现在官网默认的master分支上的demo还没法运行,那是因为demo里反射调用了hide api且light-greylist没声明的api: android.app.ActivityThread#performRestartActivity,所以现在要运行demo需要clone分支android_p

git clone https://github.com/alibaba/atlas.git -b android_p

运行后发现没有异常,但hide api在light greylist中,调用时会有警告,还好大部分都可以被反射调用。

当然也有失败的情况,不过都是一些兼容性处理的反射调用,不会影响到整个Atlas的框架。

所以从目前来看Atlas在Android不会因为hide api限制而作废

hide api 自相矛盾的现状

为什么Android会开放出light greylist来运行反射调用hide api呢?为什么没法立即执行这个限制呢?

原因很可能还是Android Studio中需要使用,Instant Run是主要使用者,而Instant Run这种机制还主要是用的插件化的思想来完成的(不清楚的自行百度instant run原理),Atlas中调用的大部分还是Instant Run需要用的,如果Android一刀切,可能自己的工具也会遭殃,所以这个是Android hide api中矛盾的现状。

总结

插件化加载的核心还是DexClassLoader的使用。就算Android未来删除了light greylist,屏蔽了所有的hide api,只要DexClassLoader可以使用,我们还是可以实现插件化开发。

上一篇 Atlas配置bundle打包产物至assets目录
下一篇 Atlas开发总结
目录
文章列表
1 EventBus 3.0 在页面间跳转接收不到消息解决方法
EventBus 3.0 在页面间跳转接收不到消息解决方法
2
React Redux管理状态
React Redux管理状态
3
Flutter Widget之BottomNavigationBar
Flutter Widget之BottomNavigationBar
4
有赞前端组件库Vant
有赞前端组件库Vant
5
Android 10(Api 29)新特性适配 - 后台应用增加定位限制
Android 10(Api 29)新特性适配 - 后台应用增加定位限制
最新评论
一位WordPress评论者
一位WordPress评论者
2月12日
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。