为方便列表,简写如下:
DyLA : Dynamic-load-apk @singwhatiwanna, 百度
DiLA : Direct-Load-apk @FinalLody
APF : Android-Plugin-Framework @limpoxe
ACDD : ACDD @bunnyblue
DyAPK : DynamicAPK @TediWang, 携程
DPG : DroidPlugin @cmzy, 360
-
功能
\ DyLA DiLA ACDD DyAPK DPG APF Small 加载非独立插件[1] × x √ √ × √ √ 加载.so后缀插件 × × ! [2] × × × √ Activity生命周期 √ √ √ √ √ √ √ Service动态注册 × × √ × √ √ x [3] 资源分包共享[4] × × ! [5] ! [5] × ! [6] √ 公共插件打包共享[7] × × × × × × √ 支持AppCompat[8] × × × × × × √ 支持本地网页组件 × × × × × × √ 支持联调插件[9] × x × × × × √ [1] 独立插件:一个完整的apk包,可以独立运行。比如从你的程序跑起淘宝、QQ,但这加载起来是要闹哪样?
非独立插件:依赖于宿主,宿主是个壳,插件可使用其资源代码并分离之以最小化,这才是业务需要嘛。
-- “所有不能加载非独立插件的插件化框架都是耍流氓”。[2] ACDD加载.so用了Native方法(libdexopt.so),不是Java层,源码见dexopt.cpp。
[3] Service更新频度低,可预先注册在宿主的manifest中,如果没有很好的理由说服我,现不支持。
[4] 要实现宿主、各个插件资源可互相访问,需要对他们的资源进行分段处理以避免冲突。
[5] 这些框架修改aapt源码、重编、覆盖SDK Manager下载的aapt,我只想说_“杀(wan)鸡(de)焉(kai)用(xin)牛(jiu)刀(hao)”。
Small使用gradle-small-plugin,在后期修改二进制文件,实现了PP_段分区。[6] 使用public-padding对资源id的_TT_段进行分区,分开了宿主和插件。但是插件之间无法分段。
[7] 除了宿主提供一些公共资源与代码外,我们仍需封装一些业务层面的公共库,这些库被其他插件所依赖。
公共插件打包的目的就是可以单独更新公共库插件,并且相关插件不需要动到。[8] AppCompat: Android Studio默认添加的主题包,Google主推的Metrial Design包也依赖于此。大势所趋。
-
透明度
\ ACDD DyAPK APF Small 插件Activity代码无需修改 √ √ √ √ 插件引用外部资源无需修改name × × × √ 插件模块无需修改build.gradle × x × √ 以上对比,纯属个人见解,如有不同意见请指出,谢谢。
File->New->New Project...
假设宿主包名为com.example.mysmall
- 设置Application name为
MySmall - 修改Company Domain为
mysmall.example.com
这步是个技巧,在Step3新建Module时将会自动带上该前缀
- 修正Package name为
com.example.mysmall
这步推荐使用Fullscreen Activity,作为启动界面再好不过。 在配置Activity界面,建议把Activity Name改为LaunchActivity(使名符其实)。
修改Project的build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'net.wequick.tools.build:gradle-small:0.8.0'
}
}
...
apply plugin: 'net.wequick.small'目前只有一个属性aarVersion,表示Small aar的代码库版本。如果没有设置,默认为gradle-small的版本。
small {
aarVersion = '1.0.0-beta1'
}最新的版本号可以在Bintray上看到。
File->New->Module来创建插件模块,需要满足:
- 模块名形如:
app.*,lib.*或者web.* - 包名包含:
.app.,.lib.或者.web.
为什么要这样?因为Small会根据包名对插件进行归类,特殊的域名空间如:“.app.” 会让这变得容易。
对lib.*模块选择Android Library,其他模块选择Phone & Tablet Module。
创建一个插件模块,比如app.main:
- 修改Application/Library name为
App.main - 修改Package name为
com.example.mysmall.app.main
右键app模块->New->Folder->Assets Folder,新建assets目录,
右键assets目录->New->File,新建bundle.json文件,加入:
{
"version": "1.0.0",
"bundles": [
{
"uri": "main",
"pkg": "com.example.mysmall.app.main"
}
]
}切换到Project目录树,右键MySmall,新建sign目录,添加release.jks签名文件。
在app模块的build.gradle中增加签名配置(密码改成自己的):
signingConfigs {
release {
storeFile file('../sign/release.jks')
storePassword "5mall@ndro!d"
keyAlias "small"
keyPassword "5mall@ndro!d"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}在app模块增加共享的依赖库,比如:
compile 'com.android.support:design:23.1.1'在app模块的LaunchActivity重载onStart方法:
@Override
protected void onStart() {
super.onStart();
Small.setBaseUri("http://example.com/");
Small.setUp(this, new net.wequick.small.Small.OnCompleteListener() {
@Override
public void onComplete() {
Small.openUri("main", LaunchActivity.this);
}
});
}- Build libraries (准备基础库)
[./]gradlew buildLib -q (-q是安静模式,可以让输出更好看,也可以不加)
- Build bundles (打包所有组件)
[./]gradlew buildBundle -q (-q是安静模式,可以让输出更好看,也可以不加)
我们鼓励大家成为Small的开发者,并享受开源协作的乐趣。
更多细节请参考开源贡献指南。
- 下载插件
- 热更新(现在需要重启生效)
- 终极分离与去除警告
- 加速生成AndroidManifest.xml
- 支持混淆
感谢以下网站收录本项目:
当你决定这么做时,希望你已经下载了源码并成功运行。并且关注
“如何从Small中学到东西以及为Small做点什么,促进共同成长。”
而非Small能为你做什么。
验证填写你是从何得知Small的,如qq, weibo, InfoQ, csdn, 朋友推荐, github搜索。
进群改备注:如_“福州-GalenLin”_。
QQ群链接无法使用的手动加 374601844
Apache License 2.0








