Android插件化开发指南
上QQ阅读APP看书,第一时间看更新

如何面对Android P的限制

写作这本书的时候,Google推出了Android P preview的操作系统,会限制对@hide api的反射调用。目前会通过log发出警告,用户代码仍然能够获取到正确的Method或Field,在后续版本中获取到的Method或Field极有可能为空。

但是道高一尺,魔高一丈。Google对这次限制,很快就被技术极客们绕过去了详细内容,请参见田维术的文章:http://weishu.me/2018/06/07/free-reflection-above-android-p/,有两种解决方法:

1)把通过反射调用的系统内部类改为直接调用。具体操作办法是,在Android项目中新建一个库,把要反射的类的方法和字段复制一份到这个库中,App对这个库的引用关系设置为provided。那么我们就可以在App中直接调用这个类和方法,同时,在编译的时候,又不会把这些类包含到apk中。

其实早在2015年,hoxkx就在他的插件化框架中实现了这种技术项目地址参见:https://github.com/houkx/android-pluginmgr。但是这种解决方案,仅限于Android系统中标记为public的方法和字段,对于protected和private就无能为力了。比如AssetsManager的addAssetPath方法,ActivityThread的currentActivityThread方法。

2)类的每个方法和字段都有一个标记,表明它是不是hide类型的。我们只要在jni层,把这个标记改为不是hide的,就可以绕过检查了。

然而,魔高一丈,道高一丈二。Google在Android P的正式版中势必会推出更严厉的限制方案,到时候,又会有新的解决方案面世,让我们拭目以待。

其实,开发者是无意和Google进行技术对抗的,这是毫无意义的。泛滥成灾的修改导致了App大量的崩溃,Google实在看不下去了,所以才搞出这套限制方案;另一方面,插件化技术是刚需,尤其在中国的互联网行业,App崩溃会直接影响使用,很可能导致经济损失,所以开发者才会不惜一切代价走插件化这条路。

再回到限制方案来,Google也不是清一色不要开发者使用系统底层的标记为hide的API,而是推出了一组黑灰名单,如下所示:

所以,另一种应对策略是,在插件化中使用浅灰名单中的API,比如说ActivityThread的currentActivityThread方法。

Google的这组清单还在持续调整中,据我所知,给各大手机厂商的清单与其在社区中发布的清单略有出入。在Android P的正式版本中,这份清单会最终确定下来。所以现在中国的各个插件化框架的开发人员,都在等Android P的正式版本发布后再制定相应的策略。留给中国队的时间不多了。