关于包管理:插件化工程R文件瘦身技术方案-京东云技术团队
随着业务的倒退及版本迭代,客户端工程中一直减少新的业务逻辑、引入新的资源,随之而来的问题就是安装包体积变大,后期各个业务模块通过无用资源删减、大图压缩或转上云、AB试验业务逻辑下线或其余伎俩在升高包体积上获得了肯定的成绩。 在瘦身的过程中咱们关注到了R文件瘦身的概念,目前京东APP是反对插件化的,有业务插件工程、宿主工程,对业务插件包文件进行剖析,发现除了惯例的资源及代码外,R类文件大略占包体积的3%~5%左右,对宿主工程包文件进行剖析,R类文件占比也有3%左右。咱们先后在对R类文件瘦身的可行性及业界开源我的项目进行调研后,摸索出了一套实用于插件化工程的R文件瘦身技术计划。 实践根底—R文件R文件也就是咱们日常工作中常常打交道的R.java文件,在Android开发标准中咱们须要将利用中用到的资源别离放入专门命名的资源目录中,内部化利用资源以便对其进行独自保护。 内部化利用资源后,咱们可在我的项目中应用R类ID来拜访这些资源,且R类ID具备唯一性。 public class MainActivity extends BaseActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}在android apk打包流程中R类文件是由aapt(Android Asset Packaing Tool)工具打包生成的,在生成R类文件的同时对资源文件进行编译,生成resource.arsc文件,resource.arsc文件相当于一个文件索引表,应用层代码通过R类ID 能够拜访到对应的资源。 R文件瘦身的可行性剖析日常开发阶段,在主工程中通过R.xx.xx的形式援用资源,通过编译后R类援用对应的常量会被编译进class中。 setContentView(2131427356);这种变动叫做内联,内联是java的一种机制(如果一个常量被标记为static final,在java编译的过程中会将常量内联到代码中,缩小一次变量的内存寻址)。 非主工程中,R类资源ID以援用的形式编译进class中,不会产生内联。 setContentView(R.layout.activity_main);产生这种景象的起因是AGP打包工具导致的。具体细节,大家能够去查阅一下android gradle plugin在R文件上的处理过程。 论断:R类id内联后程序可运行,但并非所有的工程都会主动产生内联景象,咱们须要通过技术手段在适合的机会将R类id内联到程序中,内联实现后,因为不再依赖R类文件,则能够将R类文件删除,在利用失常运行的同时,达到包瘦身目标。 插件化工程R文件瘦身实战制订技术计划目前京东Android客户端是反对插件化的,整个插件化工程蕴含公共库(是一个aar工程,用来寄存组件和宿主共用的类和资源)、业务插件(插件工程是一个独立的工程,编译产物能够运行在宿主环境中)、宿主(主工程,提供运行环境)。在插件化的过程中为了避免宿主和插件资源抵触,通过批改插件packageId保障了资源的唯一性。因为公共资源库、宿主是被很多业务依赖,对这两个我的项目进行改变评估影响波及比拟多,插件个别都是业务模块自行保护,不存在被依赖问题,所以先在业务插件模块进行R类瘦身实际。 对业务插件工程打出的包进行反编译当前,发现R类ID无内联景象,且R类文件具备肯定的大小,对包内的R文件进行剖析,发现R文件中仅蕴含业务本身的资源,不蕴含业务依赖的公共资源R类。 public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) { this.b = paramLayoutInflater.inflate(R.layout.lib_pd_main_page, paramViewGroup, false); this.h = (PDBuyStatusView)this.b.findViewById(R.id.pd_buy_status_view); this.f = (PageRecyclerView)this.b.findViewById(R.id.lib_pd_recycle_view);} 联合对业界开源我的项目的调研剖析,尝试制订合乎京东商城的技术计划并优先在业务插件内实现R类ID内联并删除对应的R文件。 1.通过transformapi 收集要解决的class文件Transform 是 Android Gradle 提供的操作字节码的一种形式,它在 class 编译成 dex 之前通过一系列 Transform 解决来实现批改.class文件。 ...