Fastlane 实战(三):Fastlane 在 Android 平台的应用

阅读数:1765 2016 年 10 月 31 日

话题:Android语言 & 开发架构

平心而论,Fastlane 本身对 Android 平台的支持力度确实有限,15 个核心工具中仅有 2 个是用于 Android 平台的,其中:

  1. Supply 是用于上传 APK 文件和同步 Meta 信息到 Google Play 商店(类似 iOS 的 Deliver)
  2. Screengrab 是用于生成各种屏幕尺寸的截屏,然后上传这些截屏到 Google Play 商店

好吧,看上去这两个工具都和 Google Play 相关,这个对于国内大部分 Android 开发者来说,似乎都派不上用场。

当然这也不能怪 Fastlane 重 iOS,轻 Android。和 iOS 不同,Android 本身就没有那么多琐碎的事情,比如:证书管理,Provisioning 文件管理,推送证书管理,签名等等,也不需要专门使用一个类似 Testflight 的测试平台来分发测试包,基本上一个 APK 打包出来,就能随便安装了。

不过俗话说得好:“家家有本难念的经”,如果从开发复杂度来比较,Android 平台其实是有过之而无不及的。功能开发完毕只是一切的开始,多系统,多屏幕,多厂商的适配,五花八门的市场分发才是真正的难题。如何快速,低成本的解决这些难题,将成为 Andriod 工程师们所面临的挑战。

多渠道打包

我相信每个公司的市场部门都希望精确的统计到各个投放渠道的安装,激活,注册,留存,变现等数据,从而能够有的放矢。这一切的数据统计都来源于渠道包的生成。由于国内 Android 市场众多,所以在最终发版的时候,我们需要提供多个渠道包给市场同学,如果手动处理的话,那么步骤大概如下:

  1. 执行 Git Pull 命令,拉最新的代码到本地
  2. 修改渠道标识,如:在 APK 的 META-INFO 目录增加一个空的文件,文件名为渠道名
  3. 执行./gradlew clean 命令清理环境
  4. 执行./gradlew assembleRelease 打包 Release 版本
  5. 将生成的 APK 文件重新命名为改渠道对应的名字

然后以上步骤重复 N 次,N= 渠道数,如果 N>=3,我相信无论是多么有耐心的人,经过两三次下来,结果都会崩溃,尤其是万一上线前发现版本中包含 Bug,那么只能重来一遍,此时 N= 渠道数 x 重来的次数。

其实我这里描述的场景可能稍显夸张,我相信大部分公司都会或多或少使用一些自动化的方式来处理,比如通过 Shell 命令等等。这里我们可以看看使用 Fastlane 如何进行处理:

首先,我们自定义一个 Action:add_channels_to_apk,这个 Action 的作用就是:

  1. 拷贝最终打包生成的 apk 文件,并修改文件名为渠道名,如 gengmei_qq_630.apk
  2. 然后将一个渠道名写入到 apk 文件的 META-INFO 目录中

其次,新建一个 txt 文件,里面写入所有需要打包的渠道名,如:QQ,360,Baidu... 等等,渠道名之间用逗号隔开。

最后,在 Fastfile 中定义一个 Lane 来进行最终的集成处理:

desc "Package a new app version with different channels"
lane :do_package_apk do |options|
    project = "#{options[:project]}"
    target_version = options[:version]

    hipchat(message: "Start package #{project} at version #{target_version}")

    git_pull
    gradle(task: "clean")
    gradle(task: "assembleRelease")
    add_channels_to_apk(channels: './channels.txt')

    hipchat(message: "Deliver app #{project} successfully!")
end

接下来的事就简单多了,每次需要打包的时候,只要执行如下的命令即可:

fastlane do_package_apk project:Gengmei version:6.3.0 

无论是 5 个渠道,还是 50 个渠道,1 分钟内全部搞定,非常的方便。

私有 AAR 发布

随着业务的发展,产品线的增加,我们需要将 APP 拆分为若干个基础组件和业务组件,以便跨 APP 使用,并且方便管理维护。每个组件都由一个私有 AAR 来管理,这些 AAR 最终会发布到内部的 Maven 仓库中(我们使用 Sonatype Nexus 搭建)。对于这些 AAR,一般我们团队内部的原则是:谁制作,谁管理,谁发布,AAR 的负责人我们内部称之为库管,这件事也就分担到了每个库管身上,库管发布一个 AAR 的流程大约如下:

  1. 执行 Git Pull 命令,拉最新的代码到本地
  2. 增加一下库的版本号
  3. 执行./gradlew clean 命令清理环境
  4. 执行./gradlew assembleRelease 打包 Release 版本
  5. 执行./gradlew upload(自定义的 Gradle 命令)将 AAR 上传到私有 Maven 仓库
  6. 由于修改了版本号,所以需要将代码 Commit 和 Push 一下
  7. 打一个 Git Tag
  8. 将 Tag Push 到远端

从本质上来看这件事和 iOS 端使用 Cocoapods 来发布一个私有 pod 库的过程基本一致,当然也面临着和 iOS 同样的问题:如果库不多并且库的更新频率较低的时候,每次手动来处理还好。但是当库逐渐增多的时候这件事就变得相当麻烦,尤其是当顶层的库依赖底层库的时候,那么升级一个库,影响面将远远超过其本身,通过人工的方式处理的话,整个过程会变得相当痛苦。

所以针对以上这个场景,我们同样可以使用 Fastlane 来解决,Lane 具体内容如下:

desc "Release a new version to the Gengmei Maven Repo"
lane :do_release_lib do |options|
    project        = options[:project]
    target_version = options[:version]
    release_notes  = options[:release_notes]

    hipchat(message: "Start release aar #{project} at version #{target_version}")
    hipchat(message: release_notes)

    git_pull
    update_gradle_version(version: target_version)
    gradle(task: "upload") # 包含 clean,release 命令 
    git_commit_all(message: "Bump version to #{target_version}") # 提交版本号修改 
    add_git_tag(tag: target_version, message: release_notes || "Bump version to #{target_version}") # 设置 tag
    push_to_git_remote # 推送到 git 仓库 

    hipchat(message: "Release aar #{project} successfully!")
end

这样,每次发布一个 AAR 的时候,我们只需要执行一个命令就能完成:

fastlane do_release_lib project:GMAlbum version:0.3.0 release_notes: 增加 xxx 功能

以上的两个场景如果结合诸如 Jenkins,Circle 等 CI 系统的话(我们使用的是内部开发的 Jaguar 系统)的话效果会更好。这样每次动动鼠标,点击一个按钮,然后泡个咖啡回来整个流程就能自动跑完了,相当的惬意。

注意事项

当在一个 Andriod 项目下使用 Fastlane 的时候,需要先初始化,执行如下的命令:

fastlane init

Fastlane 会自动检测到当前项目为 Andriod 平台,然后会引导你填写一些和项目以及 Google Play 相关的信息,需要注意的是:对于国内开发者来说,由于基本不会考虑 Google Play,所以这些信息可以快速跳过:

  1. Do you have everything commited in version control? If not please do so now!(是否已经将所有内容提交到版本控制了,如果没有尽快完成),选择 Y
  2. Package Name (com.krausefx.app)(输入包名):输入你项目的包名即可
  3. Do you plan on uploading metadata, screenshots and builds to Google Play using fastlane?(是否上传 Meta 信息,截屏等到 Google Play),选择 N

然后 Fastlane 会在你的项目下创建一个 fastlane 目录,里面包含 Appfile 和 Fastfile,以及 actions 目录,对于我们来说基本上只需要关注 FastFile 文件即可。这些内容在 Fastlane 系列的第一篇文章中有详细的讲解,不太清楚的同学可以先看一下:Fastlane 实战 (一): 移动开发自动化之道

结语

虽然 Fastlane 本身对 Andriod 平台的支持并不全面,但是得益于 Fastlane 本身灵活的架构和扩展性,我们还是可以发挥自己的想象力,将一切流程化,重复性的工作交给其处理,从而节约宝贵的时间。

更为详细的内容,大家可以参考 Fastlane 给出的 Andriod 相关的官方文档:https://docs.fastlane.tools/getting-started/android/setup/

下一篇文章,我将从移动端自动化测试的角度,详细介绍一下 Fastlane 如何发挥作用。


感谢徐川对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。