转自:http://blog.csdn.net/wdd1324/article/details/76855408
官网
文档
github
视频资料如有错误请指正!
Atlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于Android系统上的一个容器化框架,我们也叫动态组件化(Dynamic Bundle)框架。它主要提供了解耦化、组件化、动态性的支持。覆盖了工程师的工程编码期、Apk运行期以及后续运维期的各种问题。
atlas是一个组件框架,atlas不是一个多进程的框架,他主要完成的就是在运行环境中按需地去完成各个bundle的安装,加载类和资源。
atlas类加载机制---加载顺序:
1. 查找自身内部的class
2. 查找bundle依赖的bundle内的class
3. 查找主apk中的class
Bundle: 类似OSGI规范里面bundle(组件)的概念,每个bundle有自己的classloader,与其他bundle相隔离,同时Atlas框架下bundle有自身的资源段(PackageID,打包时AAPT指定);另外与原有OSGI所定义的service格式不同之处是Atlas里面Bundle透出所有定义在Manifest里面的component,随着service,activity的触发执行bundle的安装,运行。
awb: android wireless bundle的缩写,实际上同AAR类似,是最终构建整包前的中间产物。每个awb最终会打成一个bundle。awb与aar的唯一不同之处是awb与之对应有个packageId的定义。
host: 宿主的概念,所有的bundle可以直接调用host内的代码和资源,所以host常常集合了公共的中间件,UI资源等。host和bundle的依赖关系如下图所示:
1.处理资源文件
2.处理aidl文件
3.编译java文件
4.class2dex
5.apk打包
6.签名
7.zipalign对齐
参考
Gradle史上最详细解析
Android Gradle 插件中文指南
自定义Gradle插件
官方文档—>英文好的可以去看,我是看不懂- -!
module名 | 意义 |
---|---|
activitygroupcompat | demo中的工具类 |
app | 客户端代码 |
databindbundle | 使用Google bind框架demo |
firstbundle | 第一个业务bundle代码 |
lottie | splashScreen依赖的代码 |
middlewarelibrary | 中间键library,会打包到主dex中 |
publicbundle | 共bundle代码,不会打入主dex中 |
remotebundle | 远程bundle,在发布时不会编译进apk,而在客户端使用时,先下载后加载 |
secondbundle | 第二个业务bundle代码 |
secondbundlelibrary | 第二个业务单独依赖的代码 |
splashScreen | 闪屏代码 |
mavenLocal()//如果有GitHub地址就换成git上地址
classpath "com.taobao.android:atlasplugin:2.3.3.rc1"
apply plugin: 'com.taobao.atlas'//atlas插件()
compile('com.taobao.android:atlas_core:5.0.7.30@aar') {//atlas核心库
transitive = true
}
compile 'com.taobao.android:atlasupdate:1.1.4.10@aar'//atlas框架更新功能相关的库
atlas {
atlasEnabled true //atlas开关,一般接入后都打开
tBuildConfig {//
//自启动bundle配置,跟随应用启动而加载;普通bundle是随运行而加载
autoStartBundles = ['com.taobao.firstbundle']
//打包时,不打包到包中的bundle,也就是远程bundle
outOfApkBundles = ['remotebundle']
//是指在atlas框架启动前需要启动的功能(如:崩溃信息统计。。。),并且在atlas启动前的功能是不能被动态部署的!
preLaunch = 'com.taobao.demo.DemoPreLaunch'
classInject false
dataBindingBundles = ['com.taobao.databindbundle']
}
manifestOptions {
addAtlasProxyComponents true
}
patchConfigs {
debug {
createTPatch true
}
}
buildTypes {
debug {
if (apVersion) {
//基线版本坐标
baseApDependency "com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap"
patchConfig patchConfigs.debug
}
}
}
}
//这种依赖会当成bundle,打包会打包到apk的lib下,也就是我们的插件了
bundleCompile project(':firstbundle')
//compile 'com.taobao.android.atlasdemo:firstbudle:1.0.0@awb'
bundleCompile project(':secondbundle')
bundleCompile project(':remotebundle')
bundleCompile project(':publicbundle')
bundleCompile project(':databindbundle')
apply plugin: 'com.android.library' (这个要注意 这里是library不是application 并且在android中没有id设置!!!!!!)
apply plugin: 'com.taobao.atlas'//atlas插件()
atlas {
bundleConfig {
//标明这是一个bundle工程,产物会生成awb文件,也就是最后打入包中的so文件
awbBundle true
}
buildTypes {
debug {
//基线版本位置
baseApFile project.rootProject.file('app/build/outputs/apk/app-debug.ap')
}
}
}
//如果是用发布版本的方法:
/*group = 'com.taobao.android.atlasdemo'
version = "1.0.0";
apply plugin: 'maven'
apply plugin: 'maven-publish'
publishing {
repositories {
mavenLocal()
}
}
publishing {
publications {
maven(MavenPublication) {
artifact "${project.buildDir}/outputs/awb/${project.name}-debug.awb"
artifactId "firstbundle"
}
}
}*/
//依赖编译,但是不会打入包中
providedCompile project(':middlewarelibrary')
providedCompile project(':publicbundle')
资源分段
(为了避免bundle资源与apk资源冲突的问题)那怎么设置版本好呢?
我们现在在app 的build.gradle中可以看到group、version、artifactId这三个字段,标示了我们发布的路径、名称、版本
group = 'com.taobao.android.atlasdemo'
version = getEnvValue("versionName", "1.0.0");
publishing {
publications {
maven(MavenPublication) {
artifact "${project.buildDir}/outputs/apk/${project.name}-debug.ap"
artifactId "AP-debug"
}
}
}
1、 app的build.gradle的语句"version = getEnvValue("versionName", "1.0.0");"中修改想要生成的app的versionName(默认为1.0.0)
app目录下执行../gradlew clean assembleDebug 生成apk (windows 环境的命令为 ..\gradlew.bat clean assembleDebug 以下类同)
2、 app目录下执行../gradlew publish 将跟apk同目录的ap文件发布到仓库,此时ap的版本是1.0.0
3、 手机上安装生成的apk,同时进到动态部署界面(侧边栏里面划开点击进入),且手机连接电脑adb(确保adb devices可见)
///////////////////////////////^^^^^^^准备工作^^^^^^^^^^////////////////////////
4、 进行一些想要的修改(不支持manifest的修改)
5、 app工程目录下执行../gradlew clean assembleDebug -DapVersion=apVersion -DversionName=newVersion,
其中apVersion为之前打的完整apk的版本,newVersion为此次动态部署要生成的新的版本号,
例如命令 ../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1
6、 检查build/output/tpatch-debug 目录下文件是否生成,然后执行下面的命令(以下为mac下的命令,windows请修改文件分隔符)
adb push build/outputs/tpatch-debug/update-1.0.0.json /sdcard/Android/data/com.taobao.demo/cache/update-1.0.0.json
(根据你手机的当前版本推送对应版本的update-**.json,和对应的tpatch文件)
adb push build/outputs/tpatch-debug/patch-1.0.1@1.0.0.tpatch /sdcard/Android/data/com.taobao.demo/cache/patch-1.0.1@1.0.0.tpatch
7、 点击动态部署页面红色按钮执行动态部署
8、 后续继续做想要的修改,我们要变成1.0.2 (某个bundle做动态部署的时候请更新版本号,因为差量会基于版本号对比)
../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.2 这时候会生成两个 patch-1.0.2@1.0.0.tpatch patch-1.0.2@1.0.1.tpatch
根据你目前的app版本,重复6步骤,推送对应版本的update-**.json,和对应的tpatch文件。
9、 后续继续做想要的修改,我们要变成1.0.3 (某个bundle做动态部署的时候请更新版本号,因为差量会基于版本号对比)
../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.3 这时候会生成三个 patch-1.0.3@1.0.2.tpatch patch-1.0.3@1.0.1.tpatch patch-1.0.3@1.0.0.tpatch
根据你目前的app版本,重复6步骤,推送对应版本的update-**.json,和对应的tpatch文件。
10、 如果做了多次动态部署后,需要从头开始测试,请先清楚AtlasDemo根目录下的hisTpatch文件夹。
Atlas Demo里面的Activity分布比较散,为了方便大家的快速入手,这里简单介绍下个Activity的跳转关系。
splashscreen bundle是会被编译进主dex里面的,从spllashscreen的manifest文件(splashscreen/src/main/AndroidManifest.xml)我们可以看到,WelcomeActivity是接收“android.intent.action.MAIN”和“android.intent.category.LAUNCHER”的Activity,WelcomeActivity是APP的入口Activity。
在WelcomeActivity.java(splashscreen目录)中的onPostCreate通过startActivity跳转到APP的首页MainActivity(app目录)。
MainActivity其实是个壳子Activity,在其onCreate函数中我们可以看到它其实是默认加载了firstbundle的FirstBundleActivity,并设置了导航栏,关于导航栏的具体实现细节大家可以参考activitygroupcompat bundle。
通过导航栏我们可以实现在FirstBundleActivity和SecondBundleActivity之间进行跳转,FirstBundleActivity和SecondBundleActivity是属于不同的bundle,通过这种方式我们就实现了不同bundle的Activity在同一个APP中的展示。
Atlas Demo里面集成了主APK构建、动态部署构建、远程bundle构建等功能,下面我们进行单独介绍。
Atlas Demo中将主客户端代码和所有bundle都放在了一个工程下面,这也符合gradle工程的标准框架格式。
各个业务bundle可以根据业务需求修改更新各自bundle的代码。然后再通过修改app/build.gradle中的version = getEnvValue(“versionName”, “1.0.0”);来修改版本号,版本号默认为1.0.0。
../gradlew clean assembleDebug publish
命令从而进行APK打包,生成的APK文件目录是app/build/outputs/apk/app-debug.apk,上述命令也会将该目录下的ap文件发布到仓库以便于后续生成patch。adb install app/build/outputs/apk/app-debug.apk
。bundleCompile project(':remotebundle')
,atlas { tBuildConfig { outOfApkBundles = ['remotebundle'] }
。../gradlew clean assembleDebug publish
,远程bundle 路径:app/build/outputs/remote-bundles-debug。adb push app/build/outputs/remote-bundles-debug/libcom_taobao_remotebunle.so /sdcard/Android/data/com.taobao.demo/cache/libcom_taobao_remotebunle.so
。