如何实现携程动态加载插件中对aapt的改造
来源:互联网 发布:郭艾伦体测数据 编辑:程序博客网 时间:2024/06/05 01:09
前几天,携程无线部门开源了他们的插件框架,使用该框架可以方便的实现app的插件化开发和热更新。
在陈博士发表的关于该框架的blog中,有这么一段
为aapt增加–apk-module参数。
如前所述,资源ID其实有一个PackageID的内部字段。我们为每个插件工程指定独特的PackageID字段,这样根据资源ID就很容易判明,此资源需要从哪个插件apk中去查找并加载了。在后文的资源加载部分会有进一步阐述。
很多同学都很关心这里应该怎么修改aapt来实现为不同的插件工程指定不同的PackageID,这里我来分析一下aapt的源码,提供一个大概的思路吧。
个人才疏学浅,如有不对,还请携程的同学指正一下。
appt相关的源码都在framework/base/tools/aapt目录下。
首先查看ResourceTable.cpp
中的构造函数
ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type)ssize_t packageId = -1;switch (mPackageType) { case App: case AppFeature: packageId = 0x7f; break; case System: packageId = 0x01; break; case SharedLibrary: packageId = 0x00; break; default: assert(0); break;}
资源的packageId就是在这里根据packageType来确定的,其中0x01是给系统资源使用的,在R.java中可以看到系统资源的id都是以0x01开头的,0x7f是给我们的应用程序资源使用的,
同样在R.java中,你可以看到,自己的app的资源id都是以0x7f开头的。这也就是说0x01到0x7f之间的的值我们都可以作为packageId来用。
接下来我们看看是在哪里创建了ResourceTable对象。
打开Resource.cpp
,buildResources方法,就是在这个方法中构造了resourceTable对象。
status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuilder>& builder)ResourceTable::PackageType packageType = ResourceTable::App;if (bundle->getBuildSharedLibrary()) { packageType = ResourceTable::SharedLibrary;} else if (bundle->getExtending()) { packageType = ResourceTable::System;} else if (!bundle->getFeatureOfPackage().isEmpty()) { packageType = ResourceTable::AppFeature;}ResourceTable table(bundle, String16(assets->getPackage()), packageType);
可以看到这里是根据bundle的几个方法的返回值,来确定生成的资源的packageId的。
那么,我们就可以在这里做一些手脚,来生成我们自己想要的packageId。我的做法就是给bundle对象加上一个getPackageId方法,
该方法会返回我们在命令行传入的packageId。代码类似下面
else if (!bundle->getFeatureOfPackage().isEmpty()) { packageType = ResourceTable::AppFeature;} else if (bundle->getPackageId() != 0) { packageType = bundle.getPackageId();}
bundle类上还会定义一个setPackageId方法,用来保存packageId信息。
bundle对象是在Main.cpp的main方法,也就是appt程序的入口中构造出来的,下面列出一个代码片段
switch (*cp) {case 'v': bundle.setVerbose(true); break;case 'a': bundle.setAndroidList(true); break;
bundle根据命令行传入的各种参数,来设置自己的一些状态,这里我们要加入自己的逻辑,来出来–apk-module参数,同时调用setPackageId方法就好了。
另外Dr.Chen的blog中还提到了
为aapt增加–public-R-path参数。
这里无非就是在Main.cpp中检测到这个参数的时候,也保存到bundle中,然后在Resource.cpp
的writeResourceSymbols方法中,
在生成 R.java的时候,把传入的参数所指定的R.java中的变量插入到这个要生成的 R.java文件中就可以了。
以上就是我个人的一些猜测,如有不对,请大家帮忙指正。
- 如何实现携程动态加载插件中对aapt的改造
- 改造DuContact,实现动态加载
- 如何在Eclipse/RCP中动态加载我的插件??
- 改造的JQUERY 延迟加载插件
- WF 4.0中如何实现xaml工作流的动态加载
- C# 动态加载插件的实现
- flex中如何实现动态加载图片
- 如何在一个应用程序中动态加载插件
- Java8中对HashMap的改造
- android 如何动态的加载类----app插件技术
- android 如何动态的加载类----app插件技术
- android 如何动态的加载类----app插件技术
- android 如何动态的加载类----app插件技术
- android 如何动态的加载类----app插件技术
- 动态醒目提示插件jquery.pulsate的自定义改造
- spring+webwork的动态加载实现osgi的插件思想
- 【Android高级】DexClassloader和PathClassloader动态加载插件的实现
- delphi中dll综合运用的例子(动态加载插件)
- 浅谈工业级物联网项目架构设计及实施
- 临时
- JAVA成长之路
- 【POJ1939】:Diplomatic License
- Java2平台版本
- 如何实现携程动态加载插件中对aapt的改造
- 昂贵的聘礼
- LeetCode----Happy Number
- Java基本数据类型与四个运算
- txt文件导入数据库的utf-8问题
- AndroidStudio中添加第三库文件的方法
- 关于幻读
- 源码分析:Java堆的创建
- Java平台3个版本: