Atlas Demo解析

Github:https://github.com/alibaba/atlas

Demo中的Module简介

Module 含义
app Host Module
activitygroupcompat Demo中的工具类
databindbundle 使用Google Bind框架Demo
firstbundle 第一个业务bundle代码
lottie splashScreen依赖的代码
middlewarelibrary 中间键library,会打包到主dex中
publicbundle 共bundle代码,不会打入主dex中
remotebundle 远程bundle,在发布时不会编译进apk,而在客户端使用时,先下载后加载
secondbundle 第二个业务bundle代码
secondbundlelibrary 第二个业务单独依赖的代码
splashScreen 闪屏代码

在Project的build.gradle文件中引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
buildscript {

repositories {
mavenLocal() //如果有Github地址就换成Github上的地址
jcenter()
maven {
//url "http://mvnrepo.alibaba-inc.com/mvn/repository"
url "http://maven.aliyun.com/nexus/content/groups/public"
}
}

dependencies {
//classpath 'com.android.tools.build:gradle:3.1.3' //注释自带插件
classpath "com.taobao.android:atlasplugin:2.3.3.rc63"
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}

configurations.all {
resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
}

ext {
lib_atlas_core = "com.taobao.android:atlas_core:5.1.0.0@aar"
lib_atlas_update = "com.taobao.android:atlasupdate:1.1.4.21@aar"
}

allprojects {
repositories {
jcenter()
maven {
//url "http://mvnrepo.alibaba-inc.com/mvn/repository"
url "http://maven.aliyun.com/nexus/content/groups/public"
}
//maven { url 'https://jitpack.io' }
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

在app的build.gradle文件中引入

  • 应用plugin
1
apply plugin: 'com.taobao.atlas'  //atlas插件
  • 添加运行库依赖
1
2
3
4
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容器功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
1
2
3
4
5
6
7
//这种依赖会当成bundle,会打包到apk的lib/armeabi目录下,也就是我们的插件
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')

创建第二个module,即FirstBundle

  • 配置build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
apply plugin: 'com.android.library'  //(注意这里是library不是application 并且在Android中没有applicationId设置)
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"
}
}
}
*/
  • 依赖写法
1
2
3
//依赖编译,但是不会打入包中
providedCompile project(':middlewarelibrary')
providedCompile project(':publicbundle')

了解官方Demo app module 在../gradlew assembleDebug后生成文件意义

1、进入app文件目录(用as自带terminal:cd app)
2、调用构建项目gradle命令:../gradlew assembleDebug(或点击as右侧gradle中module的assembleDebug生成)
3、然后可以进入app->build->outputs->apk文件目录下可以看到两个文件:
一个是.apk debug对应的安装包文件
一个是.ap 被称为基线版本ap,将来在这个版本上,进行动态部署时需要的(动态部署时,会根据这个ap生成差量的内容)
4、logs文件夹(不必关注)
5、remote-bundles-debug文件夹:存放所有远程bundle文件
6、apk-files.txt文件:所有文件名称、路径还有md5值,是为了以后用动态部署时进行比较文件是否变化的依据。
7、atlasConfig.json文件:记录所有atlas所有配置项的值,里面包含了一些默认值。
8、atlasFrameworkProperties.json:主要记录了bundle的信息(bundle的名称、依赖、版本信息)
9、build.txt:记录gradle版本,atlas版本等信息
10、dependencies、dependencyTree-debug两个文件:记录了项目中所有依赖
11、packageIdFile.properties文件:记录了每个bundle和它们的资源分段(为了避免bundle资源与apk资源冲突的问题)
12、pluginDependencies.txt:插件的依赖(暂时不用关注)
13、version.properties文件:记录了所有依赖的版本号和及其格式

发布基线版本

  1. 在app目录下执行发布命令:../gradlew publish
  2. 打开目录:open ~/.m2/repository/
  3. 可以在目录中看到:~/.m2/repository/com/taobao/android/atlasdemo/AP-debug/1.0.0/AP-debug-1.0.0.ap 文件

那怎么设置版本号呢?我们在app的build.gradle中可以看到group、version、artifactId这三个字段,标示了发布的路径、名称、版本

1
2
3
4
5
6
7
8
9
10
11
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"
}
}
}

构建Tpatch

具体可以看demo中的Tpatch.txt文件有详细说明,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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的修改),改动完成后需要升级一下对应bundle/lib的版本号

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请修改文件分隔符)
(根据你手机的当前版本推送对应版本的update-**.json,和对应的tpatch文件)
例如,这时是第1次部署,versionName是1.0.0,所以命令行是:
adb push build/outputs/tpatch-debug/update-1.0.0.json /sdcard/Android/data/com.taobao.demo/cache/update-1.0.0.json
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、 点击动态部署页面红色按钮执行动态部署,生效后app的versionName变为了1.0.1

8、 后续继续做想要的修改,我们要变成1.0.2 (某个bundle做动态部署的时候请更新版本号(versionName),因为差量会基于版本号对比)
../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文件。

例如: 如果这时你app的versionName是1.0.1
你的命令行就是:
adb push build/outputs/tpatch-debug/update-1.0.1.json /sdcard/Android/data/com.taobao.demo/cache/update-1.0.1.json
adb push build/outputs/tpatch-debug/patch-1.0.2@1.0.1.tpatch /sdcard/Android/data/com.taobao.demo/cache/patch-1.0.2@1.0.1.tpatch

如果这时你app的versionName是1.0.0,也就是还是基线版本
你的命令行就是:
adb push build/outputs/tpatch-debug/update-1.0.0.json /sdcard/Android/data/com.taobao.demo/cache/update-1.0.0.json
adb push build/outputs/tpatch-debug/patch-1.0.2@1.0.0.tpatch /sdcard/Android/data/com.taobao.demo/cache/patch-1.0.2@1.0.0.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文件夹。

常用命令

都需要到对应包下

构建debug命令:../gradlew assembleDebug
发布基线版本命令:../gradlew publish
单模块部署命令:../gradlew assemblePatchDebug

主APK构建步骤

Atlas Demo中将主客户端代码和所有bundle都放在了一个工程下面,这也符合gradle工程的标准框架格式。

各个业务bundle可以根据业务需求修改更新各自bundle的代码。然后再通过修改app/build.gradle中的version = getEnvValue("versionName", "1.0.0");来修改版本号,版本号默认为1.0.0。

然后再在app目录下面执行../gradlew clean assembleDebug publish命令从而进行APK打包,生成的APK文件目录是app/build/outputs/apk/app-debug.apk,上述命令也会将该目录下的ap文件发布到仓库以便于后续生成patch。
如果有手机连接在pc上可以直接使用adb install安装上述APK,在app目录下执行adb install app/build/outputs/apk/app-debug.apk

如何在用户无感知的情况下,实现所有业务模块的独立动态更新

动态部署(patch)构建步骤

  1. 各个业务bundle可以根据业务需求修改更新各自bundle的代码。
  2. app工程目录下执行../gradlew clean assembleDebug -DapVersion=apVersion -DversionName=newVersion, 其中apVersion为之前打包的完整APK的版本,newVersion为此次动态部署要生成的新的版本号。 这里举一个简单的例子,例如“主APK构建”步骤的APK版本是1.0.0,我们简单更新firstbundle的业务代码或资源,然后执行../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1
  3. 检查build/output/tpatch-debug 目录下文件是否生成,将远程patch下载到你的设备上,这里演示直接在PC上执行adb命令:adb push build/outputs/tpatch-debug/update.json /sdcard/Android/data/com.taobao.demo/cache/update.json adb push build/outputs/tpatch-debug/patch-*.tpatch /sdcard/Android/data/com.taobao.demo/cache
  4. 打开Demo侧边栏,点击“动态部署模拟”,页面红色按钮执行动态部署,等待几秒钟之后APP会关闭此时说明动态部署已经成功,重启APP后就会发现自己改动的代码已经更新成功。

感兴趣的同学可以研究下update.json和tpatch文件

动态部署的主要优势:摆脱版本迭代周期限制,新增需求灵活发布;降低版本频繁发布给用户带来困扰;发现问题及时回滚;短时间内更高的覆盖率。

远程bundle构建步骤

如果在APK发布时,不想把某个bundle编译进APK,而是在客户端使用时下载后加载,该怎么办?

  1. 添加远程bundle的依赖,参考 app/build.gradle下的 bundleCompile project(':remotebundle')
  2. 声明远程bundle列表,参考 app/build.gradle下的 atlas { tBuildConfig { outOfApkBundles = ['remotebundle'] }
  3. 构建完整包,在app目录下执行 ../gradlew clean assembleDebug publish,远程bundle 路径:app/build/outputs/remote-bundles-debug
  4. 将远程so下载到你的设备上(主动下载和被动推送都可以),这里直接在PC上执行adb push app/build/outputs/remote-bundles-debug/libcom_taobao_remotebunle.so /sdcard/Android/data/com.taobao.demo/cache/libcom_taobao_remotebunle.so
  5. 打开Demo侧边栏,点击“远程组件模拟”,点击“加载远程bundle”,加载成功后就会跳到remotebundle的页面。

单bundle部署(热部署)

单bundle调试(供线下调试使用,当只更改了单个bundle的代码时,无需对整个APP进行动态部署,可以一键进行单bundle的部署调试)

  1. 修改一个bundle工程的业务代码或资源,如在firstbundle中的FirstBundleActivity的onCreate的中加一个Toast提示。
  2. 在firstbundle的目录下执行 ../gradlew clean assemblePatchDebug,然后等应用重启或者应用关闭后点击启动就可以看到Toast提示生效。

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :