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

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/18/impact-and-adaptation-of-atlas-after-android-p-prevents-calls-to-non-sdk-apis/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Android P阻止调用非sdk api后,Atlas的影响及适配
自从Android P/9.0后,Android就已经开始着手阻止App开发调用非sdk的api,也就是被标记为@hide的变量、函数、类不可以通过反射调用,否则会提示NoSuchMethod异……
<<上一篇
下一篇>>
文章目录
关闭
目 录