淘宝框架atlas基本使用说明

转自:http://blog.csdn.net/wdd1324/article/details/76855408


官网

文档
github
视频资料

如有错误请指正!

简介

Atlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于Android系统上的一个容器化框架,我们也叫动态组件化(Dynamic Bundle)框架。它主要提供了解耦化、组件化、动态性的支持。覆盖了工程师的工程编码期、Apk运行期以及后续运维期的各种问题。
atlas是一个组件框架,atlas不是一个多进程的框架,他主要完成的就是在运行环境中按需地去完成各个bundle的安装,加载类和资源。

  • atlas能做什么
    1. 工程模块的独立加载和运行
    2. 及时上线新需求、快速迭代
    3. 业务灰度与技术灰度的快速验证
    4. 动态修复线上故障
    5. 有问题及时回滚

原理—–>具体请参考官方文档

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的依赖关系如下图所示:
host和bundle的依赖关系

Android打包基础(视频课时2)

1.处理资源文件
2.处理aidl文件
3.编译java文件
4.class2dex
5.apk打包
6.签名
7.zipalign对齐
打包基础
参考

gradle基础

Gradle史上最详细解析
Android Gradle 插件中文指南
自定义Gradle插件
官方文档—>英文好的可以去看,我是看不懂- -!

接入

官方demo中文件

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 闪屏代码

在工程build.gradle文件中引入

这里写图片描述

 mavenLocal()//如果有GitHub地址就换成git上地址
 classpath "com.taobao.android:atlasplugin:2.3.3.rc1"


在appbuild.gradle文件中引入

  • 应用plugin
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容器功能
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
//这种依赖会当成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')

创建第二个module->FirstBundle

  • 配置build.gradle
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')

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

  • 1、进入app文件目录(用as自带ter: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文件 记录了所有依赖的版本好和它们的格式

atlas的apk与普通apk区别(可以观看视频 课时4)

发布基线版本

  • 在app目录下执行发布命令:../gradlew publish
  • 打开目录:open ~/.m2/repository/
  • 我们可以在目录中看到~/.m2/repository/com/taobao/android/atlasdemo/AP-debug/1.0.0/AP-debug-1.0.0.ap 文件
  • 那怎么设置版本好呢?
    我们现在在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"
        }
    }
    }

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

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文件夹。

常用命令(都需要到对应包下)

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

Activity跳转关系

Atlas Demo里面的Activity分布比较散,为了方便大家的快速入手,这里简单介绍下个Activity的跳转关系。

WelcomeActivity

splashscreen bundle是会被编译进主dex里面的,从spllashscreen的manifest文件(splashscreen/src/main/AndroidManifest.xml)我们可以看到,WelcomeActivity是接收“android.intent.action.MAIN”和“android.intent.category.LAUNCHER”的Activity,WelcomeActivity是APP的入口Activity。
manifest.png

WelcomeActivity->MainActivity

在WelcomeActivity.java(splashscreen目录)中的onPostCreate通过startActivity跳转到APP的首页MainActivity(app目录)。
WelcomeActivity.png

MainActivity->FirstBundleActivity

MainActivity其实是个壳子Activity,在其onCreate函数中我们可以看到它其实是默认加载了firstbundle的FirstBundleActivity,并设置了导航栏,关于导航栏的具体实现细节大家可以参考activitygroupcompat bundle。
MainActivity.png

MainActivity->FirstBundleActivity、MainActivity->SecondBundleActivity

通过导航栏我们可以实现在FirstBundleActivity和SecondBundleActivity之间进行跳转,FirstBundleActivity和SecondBundleActivity是属于不同的bundle,通过这种方式我们就实现了不同bundle的Activity在同一个APP中的展示。
MainActivity.png

场景构建

Atlas Demo里面集成了主APK构建、动态部署构建、远程bundle构建等功能,下面我们进行单独介绍。

问题1:如何构建一个APK,发布到各个应用市场?

主APK构建步骤:

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

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

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

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

#### 动态部署(patch)构建步骤:1. 各个业务bundle可以根据业务需求修改更新各自bundle的代码。2. app工程目录下执行`../gradlew clean assembleDebug -DapVersion=apVersion -DversionName=newVersion`, 其中apVersion为之前打的完整APK的版本,newVersion为此次动态部署要生成的新的版本号。这里举一个简单的例子,例如“主APK构建”步骤的APK版本是1.0.0,然后我简单更新firstbundle的string.xml里面的hello_blank_fragment属性为“this is fragment of firstBundle”,然后执行`../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1`。 _firstbundlepatch.png3. 检查build/output/tpatch-debug 目录下文件是否生成,将远程patch下载到你的设备上(主动下载和被动推送都可以,这里直接在PC上执行下面的命令(以下为mac下的命令,windows请修改文件分隔符): ` 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后就会发现自己改动的代码已经更新成功。
动态部署.png
动态部署结果.png
  1. 感兴趣的同学可以研究下update.json和tpatch文件
  2. 动态部署的主要优势:摆脱版本迭代周期限制,新增需求灵活发布;降低版本频繁发布给用户带来困扰;发现问题及时回滚;短时间内更高的覆盖率

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

远程bundle构建步骤:

  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的页面。

动态部署.png

调试工具

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

  1. 在设备上安装APP,设备ADB连接电脑成功。
  2. 修改一个bundle工程的代码或者资源(设置生效的标识)。
    例如,我们这里在firstbundle中的FirstBundleActivity的onCreate的中加一个Toast提示,如下
    单bundle.png
  3. bundle工程的目录下执行../gradlew clean assemblePatchDebug,然后等应用重启或者应用关闭后点击重启”)就可以看到代码生效。
    根据上述改动,我们在firstbundle的目录下执行../gradlew clean assemblePatchDebug,然后就可以看到客户端重启,Toast提示生效。

单bundle.png

猜你喜欢

转载自blog.csdn.net/blueangle17/article/details/79498195