文档章节

Gradle打包APK的一些小技巧和productFlavor配置

SuShine
 SuShine
发布于 2016/08/01 22:41
字数 1552
阅读 1247
收藏 3
点赞 0
评论 0

前言

在使用Gradle来打包Android应用之前,Android自动化打包通常会选择使用ant,ant是一种一步一步来执行任务的工具,通常打包一个apk要经过一个复杂的过程,ant工具通过一步一步完成这些过程来生成一个apk。如果要实现一个复杂一点的打包过程,它的xml配置文件的长度也是足以让你崩溃的。Gradle的出现让打包过程变得十分轻松,而且配置起来也是简单易懂。以前需要写好几天的配置文件现在只要简单的几步就能完成,配合Android Studio更加得心应手。

一个完整的打包流程如下: pic

基本的build.gradle

如果你用Android Studio生成一个项目的话,在app模块中你会看到一个build.gradle文件,这个文件就是配置这个模块的地方,大致文件结构如下:

    
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:19.0.1'
}

这里就不一行行地解释了,关于Gradle的语法可以自行Google。

这里主要有两个小技巧

  1. 签名:开发App时经常遇到Release版和Debug版共存问题,由于默认的签名不同,经常要卸载Debug版安装Release版,非常麻烦。有两种方法可以避免这种情况:1. 使用同一个签名;2. 使用不同包名
// 方法1 (签名配置方法可以Google)
android {
   buildTypes {
       debug {signingConfig signingConfigs.myConfig}
       release {signingConfig signingConfigs.myConfig}
   }
}
// 方法2 
android {
   buildTypes {
       debug {packageNameSuffix ".debug"}
   }
}
  1. Release版打包的apk文件名:通过下面的代码可以自动为生成的apk文件附加上版本和build日期,这里可以根据你的需求添加各种信息上去。
android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            def today = new Date()
            if (variant.buildType.getName().equals("release")) {
                println "Change output apk name"
                variant.outputs.each { output ->
                    output.outputFile = new File(
                            output.outputFile.parent,
                            output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + "-" + today.format('yyyyMMdd') + ".apk"))
                }
            }
        }
    }
}

BuildVariants

Gradle的Android插件中有个BuildVariants的概念,其实简单来说其实就是buildTypes+productFlavors,buildType前面我们看到过了,主要就是debug和release的分别。而productFlavors就是我们用来打包不同版本app的主要方式。从字面意思来翻译指的就是不同的“产品特点”。

Android Studio会自动根据build.gradle 生成对应的BuildVariants。比如以下代码:

android {
    productFlavors {
        free {}
        paid {}
    }
}

会生成以下的BuildVariants:

pic

productFlavors的维度

productFlavors可以是多维的,听起来好像很难理解,这里举个栗子,有如下代码:

android {
    flavorDimensions("isfree", "channel")
    productFlavors {
        free {dimension "isfree"}
        paid {dimension "isfree"}

        googleplay {dimension "channel"}
        wandoujia {dimension "channel"}
    }
}

能够生成如下的BuildVariants:

pic

这里我们就可以看到,我们有两个维度,一个是是否免费,另一个是渠道,我们能够生成2*2=4种Flavor,并且每个Flavor都有debug和release,总共就有8种不同的APK。所以理论上来说通过组合Flavor,我们可以做到各种不同的分类。

接下来我们来看看productFlavors能做什么? ### 定义渠道

在国外一般来说开发者不太需要去管渠道的问题,他们的App只需要发往GooglePlay就可以了,但是在中国,我们有众多的APK分发平台,我们的APK需要发往各种地方,在做APP统计的时候我们就需要在APK里写入一些特征变量,发送到统计平台,以区分不同的渠道,在过去用ant打包的时代,我们通常的做法就是用不同的渠道名来重复ant任务一遍一遍地打包。

如果用gradle:我们可以通过增加一个名为channel的dimension来给每一个渠道一个特殊标示,代码就是我们之前看到的。但是你可能会问,我怎么在统计的时候获取这个渠道名呢?其实很简单,Android Studio会为我们生成一个名叫BuildConfig的类,这个类有一些关于打包的静态变量,下面是一个示例:

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "me.zheteng.android.example";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "freeGoogleplay";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  public static final String FLAVOR_isfree = "free";
  public static final String FLAVOR_channel = "googleplay";
}

其实不止是渠道,通过这个类我们还可以很方便地获得这个APK的各种信息。相信大家一眼就能看出来每个字段的意思。(我们甚至还可以自定义字段)。

如果渠道非常多,你也可以通过读配置文件的方式动态生成不同的flavors。

如果我每个flavor都有点特别呢?

有的时候我们每个flavor可能不只是一个渠道名这么简单,我的ICON可能给每个渠道的有所不同,我的包名也可能有所不同。所有这些,都可以直接在这个flavor中重新定义:

android {
    productFlavors {
        googleplay {
            applicationId "me.zheteng.android.example.googleplay"
        }
    }
}

如果需要不同的源代码或资源文件,可以在app/src下新建一个名为“flavor名”的目录(这里就是googleplay)。也就是app/src/googleplay,然后这个目录下的结构和app/src/main中是一样的,打包的时候会优先使用当前flavor下的文件。

其他Gradle小技巧

Provider名称

我们知道Provider的authority是系统中全局唯一的,有时候我们要为不同的flavor将authority改成不同的,通过gradle你可以这样实现:

<provider
    android:exported="true"
    android:name="com.path.to.my.Provider"
    android:authorities="${applicationId}.provider"/>

你问我Java代码中怎么获取?难道你忘了BuildConfig了嘛?

Manifest 占位符

有些SDK会把配置在Manifest文件中的meta信息里,而不同的flavor这个信息不一样,这是我们可以通过Manifest 占位符来实现:

<meta-data android:value="${UMENG_APPKEY}" android:name="UMENG_APPKEY"/>
android {
    productFlavors {
        googleplay {
            applicationId "me.zheteng.android.example.googleplay"
            manifestPlaceholders = [UMENG_APPKEY: "我的友盟KEY"]
        }
    }
}

总结

Gradle的灵活程度超乎想象,如果基本功能无法满足你,你还可以通过自己编写Groovy插件或者task来实现无穷的可能性,欢迎将你的思路分享出来~

本文转载自:http://zheteng.me/android/2016/02/29/flavors-with-gradle/

共有 人打赏支持
SuShine
粉丝 118
博文 436
码字总数 88684
作品 0
青岛
后端工程师
Gradle 4.1更新内容及注意事项

前言 进入2017年,Android Studio 版本更新至3.0,连带着com.android.tools.build:gradle 工具也升级到了3.0.0,在3.0.0中使用了最新的Gralde 4.0 里程碑版本作为gradle 的编译版本,该版本g...

fqian ⋅ 01/11 ⋅ 0

android MultiDex multiDex原理(一)

android MultiDex 原理(一) Android分包MultiDex原理详解 转载请注明:http://blog.csdn.net/djy1992/article/details/51162013 下一篇文章:android MultiDex 原理下遇见的N个深坑(二) ...

DJY1992 ⋅ 2016/04/15 ⋅ 0

Android Studio Set of source 代码源集

一、源集 1、定义:Android Studio 按逻辑关系将每个模块的源代码和资源进行分组,这个分组叫做源集。 2、main Module 源集包括其所有构建变体共用的代码和资源。这句话很关键,意思是,所有...

Android那些事儿 ⋅ 2017/09/06 ⋅ 0

Gradle的Android插件

Android构建系统由一个Gradle的Android插件组成。 Gradle是一个高级的构建工具集,它可以管理依赖,并使你能够定义定制化的构建逻辑。Android Studio使用了一个Gradle包装器来完整地集成Gra...

WolfCS ⋅ 2015/12/23 ⋅ 0

Freeline 一款 Android平台上的秒级编译方案

参考:https://github.com/alibaba/freeline/blob/master/freeline-docs/zhcn.md Python 2.7.3 Release Win7 Python2.7 安装教程 Freeline 是什么? Freeline 是一款 Android 平台上的秒级编译......

天鬼 ⋅ 2017/11/10 ⋅ 0

gradle and studio

Gradle Plugin 用户使用指南 Gradle 作为一种新的集成工具,关于 Gradle 的配置信息,多版本构建,签名,依赖导入,依赖多工程,测试等等 build.gradle 中配置信息,都在这里。 Gradle 之构建...

掘金官方 ⋅ 2017/12/29 ⋅ 0

Android Gradle插件用户指南(译)

Android Gradle插件用户指南(译) 原文Gradle Plugin User Guide - Android Tools Project Site samples see bottom of New Build System 参考Gradle For Android Training Course 1 简介 这篇......

丁佳辉 ⋅ 2016/06/16 ⋅ 0

Gradle实现Android多渠道定制化打包

最近在项目中遇到需要实现 Apk 多渠道、定制化打包, Google 、百度查找了一些资料,成功实现了上述功能,在此记录以备不时之需,温故而知新,可以为师矣~ 需求可以总结如下: 如何实现多个 ...

玄学酱 ⋅ 2017/08/03 ⋅ 0

Android 多渠道打包

现在Android多渠道打包普遍使用的是gradle设置productFlavor方式,通过gradle aR,可以执行一个命令,打出多个包,但是这种方式每次都要走一遍打包流程,而目前很多包仅仅是渠道号不一致,并...

fneg ⋅ 2015/09/16 ⋅ 2

android多渠道-N种方法-android多渠道-N种方法---MutiChannelPackup

<h1 MutiChannelPackup<p Android多渠道打包,有网页版,Gradle版,Python版、BAT脚本、Jar版…看大家的喜好选择 META-INF渠道识别型:网页版、Python版、BAT脚本、Jar版、 Manifest渠道识别...

彭建波 ⋅ 2015/10/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 17分钟前 ⋅ 0

JavaScript零基础入门——(十一)JavaScript的DOM操作

JavaScript零基础入门——(十一)JavaScript的DOM操作 大家好,欢迎回到我们的JavaScript零基础入门。最近有些同学问我说,我讲的的比书上的精简不少。其实呢,我主要讲的是我在开发中经常会...

JandenMa ⋅ 今天 ⋅ 0

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 今天 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 今天 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 今天 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部