Android P阻止调用非sdk api后,Atlas该何去何从
0、背景
自从Android 9.0后,Android就已经开始着手阻止app开发调用非sdk的api,也就是被标记为@hide的变量、函数、类不可以通过反射调用,否则会提示NoSuchMethod异常
1、对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
2、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试一试
3、死而后生,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
运行后发现没有了之前的异常,但会有如下提示
05-27 04:37:31.077 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ApplicationPackageManager;->mPM:Landroid/content/pm/IPackageManager; (light greylist, reflection)
05-27 04:37:31.077 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/content/pm/ParceledListSlice;-><init>(Ljava/util/List;)V (light greylist, linking)
05-27 04:37:31.115 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/content/pm/PackageParser;-><init>()V (light greylist, reflection)
05-27 04:37:31.115 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/content/res/StringBlock;-><init>(JZ)V (light greylist, reflection)
05-27 04:37:31.115 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityThread;->mInstrumentation:Landroid/app/Instrumentation; (light greylist, reflection)
05-27 04:37:31.115 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityThread;->mAllApplications:Ljava/util/ArrayList; (light greylist, reflection)
05-27 04:37:31.115 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityThread;->mInitialApplication:Landroid/app/Application; (light greylist, reflection)
05-27 04:37:31.115 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityThread;->mPackages:Landroid/util/ArrayMap; (light greylist, reflection)
05-27 04:37:31.115 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityThread;->sPackageManager:Landroid/content/pm/IPackageManager; (light greylist, reflection)
05-27 04:37:31.116 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/LoadedApk;->mApplication:Landroid/app/Application; (light greylist, reflection)
05-27 04:37:31.116 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/LoadedApk;->mResources:Landroid/content/res/Resources; (light greylist, reflection)
05-27 04:37:31.116 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/LoadedApk;->mResDir:Ljava/lang/String; (light greylist, reflection)
05-27 04:37:31.116 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/LoadedApk;->mClassLoader:Ljava/lang/ClassLoader; (light greylist, reflection)
05-27 04:37:31.116 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/LoadedApk;->mBaseClassLoader:Ljava/lang/ClassLoader; (light greylist, reflection)
05-27 04:37:31.116 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/LoadedApk;->mAppDir:Ljava/lang/String; (light greylist, reflection)
05-27 04:37:31.116 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ContextImpl;->mResources:Landroid/content/res/Resources; (light greylist, reflection)
05-27 04:37:31.117 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ContextImpl;->mTheme:Landroid/content/res/Resources$Theme; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/view/ContextThemeWrapper;->mTheme:Landroid/content/res/Resources$Theme; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/view/ContextThemeWrapper;->mResources:Landroid/content/res/Resources; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/ContextWrapper;->mBase:Landroid/content/Context; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Component;->intents:Ljava/util/ArrayList; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Package;->activities:Ljava/util/ArrayList; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Package;->services:Ljava/util/ArrayList; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Package;->receivers:Ljava/util/ArrayList; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Package;->providers:Ljava/util/ArrayList; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Package;->applicationInfo:Landroid/content/pm/ApplicationInfo; (light greylist, reflection)
05-27 04:37:31.118 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Package;->packageName:Ljava/lang/String; (light greylist, reflection)
05-27 04:37:31.119 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$ActivityIntentInfo;->activity:Landroid/content/pm/PackageParser$Activity; (light greylist, reflection)
05-27 04:37:31.119 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$ServiceIntentInfo;->service:Landroid/content/pm/PackageParser$Service; (light greylist, reflection)
05-27 04:37:31.119 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$ProviderIntentInfo;->provider:Landroid/content/pm/PackageParser$Provider; (light greylist, reflection)
05-27 04:37:31.119 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/content/pm/PackageParser$Provider;->info:Landroid/content/pm/ProviderInfo; (light greylist, reflection)
05-27 04:37:31.119 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityManager;->IActivityManagerSingleton:Landroid/util/Singleton; (light greylist, reflection)
05-27 04:37:31.119 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/util/Singleton;->mInstance:Ljava/lang/Object; (light greylist, reflection)
05-27 04:37:31.120 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityThread$AppBindData;->providers:Ljava/util/List; (light greylist, reflection)
05-27 04:37:31.120 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ActivityThread;->mBoundApplication:Landroid/app/ActivityThread$AppBindData; (light greylist, reflection)
05-27 04:37:31.120 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden field Landroid/app/ContextImpl;->mPackageInfo:Landroid/app/LoadedApk; (light greylist, reflection)
05-27 04:37:31.121 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread; (light greylist, reflection)
05-27 04:37:31.121 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/content/res/AssetManager;->addAssetPath(Ljava/lang/String;)I (light greylist, reflection)
05-27 04:37:31.121 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/content/res/AssetManager;->addAssetPathAsSharedLibrary(Ljava/lang/String;)I (light greylist, reflection)
05-27 04:37:31.121 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/app/Application;->attach(Landroid/content/Context;)V (light greylist, reflection)
05-27 04:37:31.121 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/content/pm/PackageParser$Component;->getComponentName()Landroid/content/ComponentName; (light greylist, reflection)
05-27 04:37:31.121 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/app/ContextImpl;->setOuterContext(Landroid/content/Context;)V (light greylist, reflection)
05-27 04:37:31.122 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/content/res/AssetManager;->getResourceIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I (light greylist, reflection)
05-27 04:37:31.122 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/app/ActivityThread;->installContentProviders(Landroid/content/Context;Ljava/util/List;)V (light greylist, reflection)
05-27 04:37:31.122 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/app/ActivityThread;->installProvider(Landroid/content/Context;Landroid/app/ContentProviderHolder;Landroid/content/pm/ProviderInfo;ZZZ)Landroid/app/ContentProviderHolder; (light greylist, reflection)
05-27 04:37:31.122 2972-2972/com.taobao.demo W/com.taobao.dem: Accessing hidden method Landroid/app/Service;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Ljava/lang/String;Landroid/os/IBinder;Landroid/app/Application;Ljava/lang/Object;)V (light greylist, reflection)
hide api在light greylist中,调用时都会有警告,但还好大部分都可以被反射调用了
当然也有失败的情况:
0 = {Hack$HackDeclaration$HackAssertionException@5211} "android.taobao.atlas.hack.Hack$HackDeclaration$HackAssertionException: java.lang.NoSuchFieldException: No field mStringBlocks in class Landroid/content/res/AssetManager; (declaration of 'android.content.res.AssetManager' appears in /system/framework/framework.jar)"
1 = {Hack$HackDeclaration$HackAssertionException@5212} "android.taobao.atlas.hack.Hack$HackDeclaration$HackAssertionException: java.lang.NoSuchMethodException: ensureStringBlocks []"
2 = {Hack$HackDeclaration$HackAssertionException@5213} "android.taobao.atlas.hack.Hack$HackDeclaration$HackAssertionException: java.lang.NoSuchMethodException: addAssetPathNative [class java.lang.String]"
3 = {Hack$HackDeclaration$HackAssertionException@5214} "android.taobao.atlas.hack.Hack$HackDeclaration$HackAssertionException: java.lang.NoSuchMethodException: addAssetPathNative [class java.lang.String, boolean]"
4 = {Hack$HackDeclaration$HackAssertionException@5215} "android.taobao.atlas.hack.Hack$HackDeclaration$HackAssertionException: java.lang.NoSuchMethodException: addAssetPathNative [class java.lang.String, int]"
5 = {Hack$HackDeclaration$HackAssertionException@5216} "android.taobao.atlas.hack.Hack$HackDeclaration$HackAssertionException: java.lang.NoSuchMethodException: getStringBlockCount []"
6 = {Hack$HackDeclaration$HackAssertionException@5217} "android.taobao.atlas.hack.Hack$HackDeclaration$HackAssertionException: java.lang.NoSuchMethodException: getNativeStringBlock [int]"
不过这些都是一些兼容性处理的反射调用,不会影响到整个atlas的框架。
所以从目前来看atlas在Android不会因为hide api限制而作废
4、hide api 自相矛盾的现状
为什么Android会开放出light greylist来运行反射调用hide api呢?为什么没法立即执行这个限制呢?
原因很可能还是Android studio中需要使用,Instant Run是主要使用者,而Instant Run这种机制还主要是用的插件化的思想来完成的(不清楚的自行百度instant run原理),atlas中调用的大部分还是Instant Run需要用的,如果Android一刀切,可能自己的工具也会遭殃,所以这个是Android hide api中矛盾的现状。
5、未来,未知...
如果Android未来删除了light greylist、如果Android p正式版的限制更加严格、甚至Android更改了activity的启动源码,这都不好说,有许多未知问题,不过这不是因为Android自身问题,而是这些api本身就是隐藏的。但是,插件话加载的核心还是DexClassLoader的使用。
6、未来,猜测
就算Android屏蔽了所有的hide api,只要DexClassLoader可以使用,我们还是可以实现插件化开发,以后减少对Android系统组件依赖,使用weex、rn解耦可能是趋势,而阿里巴巴现在本身一直都在推广weex,集团下app大都也是插件化和weex并用,所以我们就等待安心等待Android p的到来、未来的到来。
Android P阻止调用非sdk api后,Atlas该何去何从相关推荐
- Android Q (十八) 非 SDK 接口在 Android Q 中的受限情况出现变化
非 SDK 接口在 Android Q 中的受限情况出现变化 为了帮助确保应用稳定性和兼容性,此平台开始限制您的应用可在 Android 9(API 级别 28)中使用的非 SDK 接口.Androi ...
- android 非SDK API blacklist处理
现象:Android P上的提醒弹窗 (Detected problems with API compatibility(visit g.co/dev/appcompat for more info) ...
- android第三方视频解码器Vitamio SDK使用后的感觉(2014.03.11)
Vitamio官方网址:http://www.vitamio.org/ Vitamio SDK下载地址: https://github.com/yixia/VitamioBundle Vitamio ...
- android利用反射调用截屏api,Android利用反射机制调用截屏方法和获取屏幕宽高的方法...
想要在应用中进行截屏,可以直接调用 View 的 getDrawingCache 方法,但是这个方法截图的话是没有状态栏的,想要整屏截图就要自己来实现了. 还有一个方法可以调用系统隐藏的 screen ...
- Android开发如何调用百度翻译api
这里只介绍核心方法,其他可参考官方文档 百度翻译开放平台百度翻译开放平台提供通用翻译API.定制化翻译API.图片翻译SDK及语音翻译SDK服务,全面满足开发者的翻译需求.https://fanyi- ...
- 适配 Android P之非SDK接口限制的排查方法
code小生,一个专注 Android 领域的技术平台 公众号回复 Android 加入我的安卓技术群 作者:天才木木链接:https://www.jianshu.com/p/efe6690b36b6 ...
- Android P非SDK接口限制
写在前头 Android Pie(API 28)开始对非SDK接口的使用开始做了限制.只要应用引用非 SDK 接口或尝试使用反射或 JNI 来获取其句柄,就会被限制.这些限制旨在帮助提升用户体验和开发 ...
- Android 非 SDK 接口常见问题
常规问题 Q1: 什么是非 SDK 接口? A:非 SDK 接口指不在官方Android SDK涵盖范围内的 Java 字段和方法.此类接口是 SDK 的内部实现细节,可能随时会被修改,且不对开发者另 ...
- Android P 访问非SDK 接口
Android P 如何访问非SDK 接口 为什么要访问非SDK 接口? 为了让应用能获得更多的系统属性.资源,扩展功能等. 在Android P 之前,我们可以使用反射来访问系统内部分 hide/p ...
最新文章
- python大数据搜索_python语言-用 Python 实现一个大数据搜索引擎
- 直播回顾丨B2B 企业如何高效获客增长
- 谈谈关于MVP模式中V-P交互问题
- gitlab bash_如何编写Bash一线式以克隆和管理GitHub和GitLab存储库
- jQuery Mobile中jQuery.mobile.changePage方法使用详解
- restfull api 接口 规范
- 可编辑杂志模板|简单的得到一个完整的杂志预先设计版式
- @Autowired的作用
- android切图倍数,【Flutter工具】fmaker:自动生成倍率切图/自动更换App图标
- 项目中的常量是放在接口里还是放在类里呢?
- HDU4681 String(dp)
- 关于Opencv出现的错误“ 0x000007fefdf6a06d (KernelBase.dll) Microsoft C++ 异常的几种尝试解决方式
- VMware虚拟机磁盘文件vmdk单文件转多文件相互转换
- u盘是传播计算机病毒的媒介,u盘病毒有几种传播方式
- java/kafka的使用,生产者 ,发布/发送消息,自定义数据/json数据,实战。
- 摄影口诀--针对不同情景
- STP特性(Cisco)
- Hybrid App开发实战
- 不可小觑的吃内存大户
- js省市县三级联动效果实例