Android Studio分模块自动化构建实战

Android Studio分模块自动化构建实战

@author ASCE1885的 Github 简书 微博 CSDN

最近在使用Android Studio+Gradle做一个基础框架SDK项目,该框架主要实现每个app都需要的基础能力,例如网络请求,图片缓存,json解析,日志记录等等。

众所周知,AndroidStudio中应该尽量使用Module来进行模块的划分,既能达到模块解耦的目的,也能在必要的时候轻松实现分模块打包,特别是在SDK项目中。那么什么是分模块打包呢?就是我们可以根据第三方使用者的需求,自动化的提供SDK的全量版本,部分功能版本以及最小功能版本等等。

我们的项目结构如下所示,每个功能独立成一个Module:

由于我们的模块都是纯代码的,没有包含资源文件,因此不是以aar包的形式而是使用jar包形式对外提供。顺便提一句,生成的aar包默认路径是:

build/output/aar/

而jar包可以到如下路径寻找:

build/intermediates/bundles/debug/classes.jar
build/intermediates/bundles/release/classes.jar

Jar包的合并

从项目工程截图中可以看到,我们的project包含多个module,每个基础功能的module最终编译生成的都是一个classes.jar。因此project最终会生成一堆的jar包,而到了对外发布时,我们要提供一个单独的jar包出去,因此,就需要对jar包进行合并。很不幸,Android Studio没有提供这样的功能,因此只能靠自己写脚本调用jar命令来实现了,打开命令行terminal,输入jar,就可以打印出jar的用法,如下所示:

guhaoxindeMacBook-Pro:~ guhaoxin$ jar
用法: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
选项包括:
    -c  创建新的归档文件
    -t  列出归档目录
    -x  从档案中提取指定的 (或所有) 文件
    -u  更新现有的归档文件
    -v  在标准输出中生成详细输出
    -f  指定归档文件名
    -m  包含指定清单文件中的清单信息
    -e  为捆绑到可执行 jar 文件的独立应用程序
        指定应用程序入口点
    -0  仅存储; 不使用情况任何 ZIP 压缩
    -M  不创建条目的清单文件
    -i  为指定的 jar 文件生成索引信息
    -C  更改为指定的目录并包含其中的文件
如果有任何目录文件, 则对其进行递归处理。
清单文件名, 归档文件名和入口点名称的指定顺序
与 ‘m‘, ‘f‘ 和 ‘e‘ 标记的指定顺序相同。

示例 1: 将两个类文件归档到一个名为 classes.jar 的归档文件中:
       jar cvf classes.jar Foo.class Bar.class
示例 2: 使用现有的清单文件 ‘mymanifest‘ 并
           将 foo/ 目录中的所有文件归档到 ‘classes.jar‘ 中:
       jar cvfm classes.jar mymanifest -C foo/ .

使用jar命令,主要实现两个功能:

  • 将所有jar包的class文件解压到某个目录中
  • 将解压后所有class文件的重新压缩为一个单独的jar包

由于jar命令不能指定最终输出的目录,因此我们需要首先cd到用于存放解压后class文件的一个临时目录,然后依次对所有jar包进行解压操作,解压命令如下所示:

jar -xvf ../../hfasynchttp/build/intermediates/bundles/debug/classes.jar

当所有的jar包都解压完毕后,接着执行压缩命令,这样就得到一个单独的jar包了:

jar -cvfM AndroidHyperion_${version}_debug.jar .

分模块自动化构建

自动化构建包括本地构建和Jenkins构建两部分,本地构建主要用于开发自己调试使用,Jenkins构建主要用于测试,产品等取包以及跑Monkey使用。

本地构建

本地构建脚本文件位于工程根目录下的build_local.sh,该脚本的主要功能有:

  • 调用gradlew命令执行gradle编译,生成各个Module的jar包
  • 解压各个Module生成的jar包,并把解压后的class文件重新打包成单独的一个jar包
  • 分模块打包功能通过定义Boolean变量值进行控制
  • 输出目录是output

build_local.sh文件内容如下:

#!/bin/sh

#使用Gradle编译各个module
./gradlew clean
./gradlew build --stacktrace --debug

#进入输出目录
cd output

#清空输出目录
rm -rf  *

#创建输出子目录
mkdir temp
mkdir debug
mkdir release

#定义sdk版本号
version="1.0.0"

#定义模块是否打包标识
is_include_hfasynchttp=true
is_include_bitmapfun=true
is_include_hfjson=true
is_include_hflogger=true
#省略其他...

#解压所有debug版本的jar包到temp目录中
cd temp

if $is_include_hfasynchttp; then
    jar -xvf ../../hfasynchttp/build/intermediates/bundles/debug/classes.jar
fi

if $is_include_bitmapfun; then
    jar -xvf ../../hfbitmapfun/build/intermediates/bundles/debug/classes.jar
fi

if $is_include_hfjson; then
    jar -xvf ../../hfjson/build/intermediates/bundles/debug/classes.jar
fi

if $is_include_hflogger; then
    jar -xvf ../../hflogger/build/intermediates/bundles/debug/classes.jar
fi

#压缩所有debug版本的class文件到一个独立的jar包中
jar -cvfM AndroidHyperion_${version}_debug.jar .

#拷贝文件
mv AndroidHyperion_${version}_debug.jar ../debug

#清空temp目录
rm -rf *

#解压所有release版本的jar包到temp目录中
if $is_include_hfasynchttp; then
    jar -xvf ../../hfasynchttp/build/intermediates/bundles/release/classes.jar
fi

if $is_include_bitmapfun; then
    jar -xvf ../../hfbitmapfun/build/intermediates/bundles/release/classes.jar
fi

if $is_include_hfjson; then
    jar -xvf ../../hfjson/build/intermediates/bundles/release/classes.jar
fi

if $is_include_hflogger; then
    jar -xvf ../../hflogger/build/intermediates/bundles/release/classes.jar
fi

#压缩所有release版本的class文件到一个jar包中
jar -cvfM AndroidHyperion_${version}_release.jar .

#拷贝文件
mv AndroidHyperion_${version}_release.jar ../release

#删除temp目录
cd ..
rm -rf temp

Jenkins构建

Jenkins编译脚本文件位于工程根目录下的build_jenkins.sh,该脚本的主要功能有:

  • 调用gradlew命令执行gradle编译,生成各个Moudle的jar包
  • 解压各个Module生成的jar包,并把解压后的class文件重新打包成单独的一个jar包
  • 分模块打包功能通过Jenkins上面配置的参数化构建参数进行控制
  • 输出目录是output

可以看到,和本地构建唯一的区别就是分模块的参数化构建参数是定义在Jenkins上的,而不是定义在本地脚本中的,为了完整清晰起见,我们还是把完整的脚本文件贴出来:

#!/bin/sh

./gradlew clean
./gradlew build --stacktrace --debug

#进入输出目录
cd output

#清空输出目录
rm -rf  *

#创建输出子目录
mkdir temp
mkdir debug
mkdir release

cd temp

#解压所有debug版本的jar包
if $is_include_hfasynchttp; then
    jar -xvf ../../hfasynchttp/build/intermediates/bundles/debug/classes.jar
fi

if $is_include_bitmapfun; then
    jar -xvf ../../hfbitmapfun/build/intermediates/bundles/debug/classes.jar
fi

if $is_include_hfjson; then
    jar -xvf ../../hfjson/build/intermediates/bundles/debug/classes.jar
fi

if $is_include_hflogger; then
    jar -xvf ../../hflogger/build/intermediates/bundles/debug/classes.jar
fi

#压缩所有debug版本的class文件到一个jar包中
jar -cvfM AndroidHyperion_${version}_debug.jar .

#移动生成的jar包到debug目录
mv AndroidHyperion_${version}_debug.jar ../debug

#清空temp目录
rm -rf *

#解压所有release版本的jar包
if $is_include_hfasynchttp; then
    jar -xvf ../../hfasynchttp/build/intermediates/bundles/release/classes.jar
fi

if $is_include_bitmapfun; then
    jar -xvf ../../hfbitmapfun/build/intermediates/bundles/release/classes.jar
fi

if $is_include_hfjson; then
    jar -xvf ../../hfjson/build/intermediates/bundles/release/classes.jar
fi

if $is_include_hflogger; then
    jar -xvf ../../hflogger/build/intermediates/bundles/release/classes.jar
fi

#压缩所有release版本的class文件到一个jar包中
jar -cvfM AndroidHyperion_${version}_release.jar .

#移动生成的jar包到release目录
mv AndroidHyperion_${version}_release.jar ../release

#删除temp目录
cd ..
rm -rf temp

local和Jenkins参数化构建参数定义

类型 名称 默认值 描述
String version 1.0.0 Hyperion sdk版本号
Boolean is_include_hfasynchttp true 是否打包hfasynchttp
Boolean is_include_bitmapfun true 是否打包hfbitmapfun
Boolean is_include_hfjson true 是否打包hfjson
Boolean is_include_hflogger true 是否打包hflogger
时间: 2024-10-22 07:21:25

Android Studio分模块自动化构建实战的相关文章

Android Studio的优化/Gradle构建

转自链接http://bbs.itheima.com/thread-204217-1-1.html 使用Android Studio进行开,随着项目的增大,依赖库的增多,构建速度越来越慢,现在最慢要6分钟才能build一个release的安装包,在网上查找资料,发现可以通过一些配置可以加快速度,这里跟大家分享一下. 开启gradle单独的守护进程 在下面的目录下面创建gradle.properties文件: /home//.gradle/ (Linux) /Users//.gradle/ (Ma

Android Studio 1.0.2项目实战——从一个APP的开发过程认识Android Studio

Android Studio 1.0.1刚刚发布不久,谷歌紧接着发布了Android Studio 1.0.2版本,和1.0.0一样,是一个Bug修复版本.在上一篇Android Studio 1.0.1 + Genymotion安卓模拟器打造高效安卓开发环境,我们介绍了Android开发环境的搭建,今天先来说一下上一篇中大家问道比较多的问题,然后说一些Android Studio的使用技巧.  一.搭建开发环境中遇到的问题及解决办法 1.Genymotion模拟器网络错误 我们顺利的安装完了G

android studio删除模块指定

android studio 不能直接删除模块,应为一般的模块是被引用的. 1.选中需要删除的模块 看有没得delete? 2.没有,点击左上角的file,点击 project structure 3.选中app模块,点击右边模块参数最右边的一个dependencies 有你这个应用引用的v4,v7包和模块. 4.选中你要删除的模块,右键remove 5.左边栏目中选中你要删除的模块,然后点击左上角落的'-' 减号.保存返回项目开发栏. 6.现在可以在开发栏中右键选中你要删除的模块,看看是否出现

android studio gradle自动签名构建实现

一.在android studio中生成签名文件. 1.在android studio 选中项目,在菜单栏中选择Build. 2.点击Generate Signed APK选项卡. 3.将生成好的jks文件拷贝到项目文件中,我的项目结构目录是这样的. 二.在构建文件中加入自己签名的相关信息. signingConfigs { myConfig { storeFile file("**.jks") storePassword "**" keyAlias "*

Android Studio分渠道打包

今天一个小伙伴问我如何分渠道打包,我翻了翻之前的工程,找了一个Demo给他.基本步骤还是比较简单的. 环境: 使用Android studio 或者直接用Gradle 在AndroidManifest.xml中增加一个 placeholder, placeholder的名称由你使用的统计服务而定,如果你用的是友盟,那么需要添加一个 meta-data 如下所示: <meta-data android:name="UMENG_CHANNEL" android:value="

Android Studio体验(一)--Window版本安装

如果说之前看见有人用Android Studio你还是不屑一顾的话,那么现在该改变态度了,正如我一样,之前一直习惯于Android内置ADT插件的捆绑Ecliple,现在Android Studio发布会已经过去了12天,年底加班加的都已经无力吐槽,更何况学习了.其实在之前自己也下载过0.8.14的版本,不过当时存在一些问题加上时间不够无奈就放弃了,换个IDE总是需要时间熟悉的.现在Android Studio已经进入了稳定版,作为亲儿子以后将成为Android开发主流的IDE,同时 Andro

Android Studio下项目构建的Gradle配置及打包应用变体

Gradle简介 ??Gradle是一个自动化构建工具,采用Groovy的Domain Specific Language(领域特定语言)来描述和控制构建逻辑.具有语法简洁.可读性强.配置灵活等特点.基于Intellij IDEA社区版本开发的Android Studio天生支持Gradle构建程序.Groovy是一种基于JVM的敏捷开发语言,结合了Phthon.Ruby和Smalltalk的许多强大特性.同时,Groovy代码既能够与java代码很好地结合,也能够用于扩展现有的代码. Grad

android studio+grade配置构建

Android 构建系统编译应用资源和源代码,然后将它们打包成可供您测试.部署.签署和分发的 APK.android Studio 使用 Gradle 这一高级构建工具包来自动化执行和管理构建流程,同时也允许您定义灵活的自定义构建配置.每个构建配置均可自行定义一组代码和资源,同时对所有应用版本共有的部分加以重复利用.Android Plugin for Gradle 与这个构建工具包协作,共同提供专用于构建和测试 Android 应用的流程和可配置设置. Gradle 和 Android 插件独

Gradle自动实现Android组件化模块构建

背景 随着App的不断迭代,业务会变得越来越复杂,业务模块会越来越多,且每个模块的代码也会变得越来越多.为了应对这一场景,我们需要把不同的业务模块划分成一个个组件,在修改业务代码的时候只需要在对应模块修改就可以了.通过高内聚,低耦合的业务模块来保证工程的健壮性和稳定性.现在问题来了,当组件的数量变得越来多的时候,我们如何管理业务组件呢? 原创声明: 该文章为原创文章,未经博主同意严禁转载. 为什么我们要用Gradle管理组件呢? 先来看看Android组件化需要实现的目标.(什么是组件化构建?)