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

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 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;
}
}
1
2
3
4
5
6
7
8
9
/**
* 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

1
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可以使用,我们还是可以实现插件化开发。

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :