在项目开发过程中,经常会有需要打包不同版本的 APK 的需求。 比如 debug版,release版,dev版等等。 有时候不同的版本中使用到的不同的服务端api域名也不相同。 比如 debug_api.com,release_api.com,dev_api.com等等。

不同的版本对应了不同的 api 域名,还可能对应不同的 icon 等。

如果每次都在打包前修改我们都手动来修改,这样实在是不够方便。

但如果我们使用了 Android Studio 和 Gradle,这个麻烦就可以轻松省去。

具体方式如下: 在 Android Studio 中打开 build.gradle(Module中)的 android 节点下添加如下代码

buildTypes {

    //这里的名字自定义,不要求大小写
release{ // 这里是在 applicationId 中添加了一个后缀。所以『.』要加上
applicationIdSuffix ".release" // 这里的作用是选择是否混淆代码
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} dev{
applicationIdSuffix ".dev"
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }
} // 这里是为了不同过的版本设置一些特殊的参数,并不直接和 buildType 关联。
//例如:使用 buildType 中的 dev 版本,也可以使用 flavors_release 里面设置的自定义参数。这需要自己按照需求制定。
productFlavors{ //自定义名字不过不能和上面buildType中相同,不然Gradle编译会不通过。在这里使用了『flavors_』前缀以便区分。
flavors_release{ // manifestPlaceholders中写到的『str』,『package_name』不支持用大写,否则Gradle编译会不通过。
// 这里所设置的变量可以直接使用在『AndroidManifest.xml』中,使用方式为:${package_name}
// android:label="${package_name}"
manifestPlaceholders = [str:"releaseStr",package_name:"com.sunhz.mvptest.release"] // 这里的参数是为了在 java 代码中使用,具体的使用方式为:context.getResources().getString(R.string.strKey);
resValue("string" , "strKey","releaseStrValue")
} flavors_dev{
manifestPlaceholders = [str:"devStr",package_name:"com.sunhz.mvptest.dev"] resValue("string" , "strKey","devStrValue")
}
}

上面设置完成后,我们要在哪里使用它?

使用方式如下: 在 Android Studio 的工具栏中,找到『Build』项,找到『Generate Signed APK…』,如下图。

选择 Module -> 创建 APK key,或者输入 APK key密码 -> 关键来了!如下图。

在『BuildType』处,选择我们在 build.gradle 中设置的两个 BuildType,分别是releas,dev,debug。其中『debug』为 Android Studio 自带的。

在『Flavors』处,选择我们在 build.gradle 中设置的两个Flavors,以方便直接使用定义在 build.gradle 中自定义的参数。

所以! 上面我有提到说,buildType 和 Flavors 并没有直接的联系。 他们可以根据用户需求互相配合使用。如上图,BuildType 选择了 release,但 Flavors 选择的却是 flavors_dev。

到此基本的使用就全部说完了。

这里有一个问题,打出来的不同版本的包,全部都能够在同一部手机上安装,且能够将两个包全都发布到 Google 的市场上去这是为什么呢?

这里就要提到在 BuildType 中我们所设置的『applicationIdSuffix』属性了,按照这个属性的字面翻译为:『applicationId 的后缀』,那这里又来了一个问题,『applicationId』是什么? 其实这个『applicationId』属性,实际上在项目创建完成后就存在于 build.gradle 中。在 android 节点下的 defaultConfig 节点中。而且默认的 applicationId 和 AndroidManifest.xml 中的 package 属性相同。

如下图:

我们能够看到,这两个属性的默认值是相同的。

applicationId 和 packageName 它们是什么关系?

默认创建项目后,两者相同。如果需要根据不同的需求构建不同版本的APK,这时我们通过设置『applicationIdSuffix』可以做到。

这里有一个值得注意的现象。

举个例子,我们在打包时使用了 dev 类型,将打包出来的 APK 软件安装到手机中。

使用如下代码,获取我们手机上所有程序的packageName。

PackageManager packageManager = mContext.getPackageManager();
List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS);
List<String> packageNameList = new ArrayList<String>();
for (PackageInfo packageInfo : packageInfoList) {
packageNameList.add(packageInfo.packageName);
}

我们打印出来的包名信息中,会出现 com.spencer_dev.test.dev 。并没有出现 com.spencer_dev.test 。

但是! 如果通过反编译工具,将 APK 包进行反编译直接查看源代码,在 java 代码所在的 src 目录中的包名,还和我们设置的一样,为 com.spencer_dev.test 。可 AndroidManifest.xml 中的 package 和 BuildConfig 类中的 APPLICATION_ID 已经变成了 com.spencer_dev.test.dev 。

applicationId 和 packageName 它们各自代表什么?

按照上面的结果来说, package 代表了 java 代码中的包名。 applicationId 代表了应用中的唯一标识。和应用签名一起用来区别和其他应用不同。我想这也就是为什么 Google 市场能够允许相同应用不同 applicationId 的原因。

关于更多的 applicationId 和 packageName 详解,请看这里。 ApplicationId 与 PackageName

利用 Android Studio 和 Gradle 打包多版本APK的更多相关文章

  1. Android 项目利用 Android Studio 和 Gradle 打包多版本APK

    在项目开发过程中,经常会有需要打包不同版本的 APK 的需求. 比如 debug版,release版,dev版等等. 有时候不同的版本中使用到的不同的服务端api域名也不相同. 比如 debug_ap ...

  2. Android Studio 使用 Gradle 打包 Jar

    Android Studio 打 Jar 包一直是一个麻烦的事,按照网上现有的教程,打包一个混淆的 jar 需要完成下列步骤: 1.将 plugin 修改为 library 后 build 出 aar ...

  3. MUI离线原生打包,利用Android Studio进行原生打包MUI项目

    首先从官网http://www.dcloud.io/ 下载HBuilder,用该软件创建一个HTML5的移动APP项目,具体可去官网查看相应的文档. 接下来就是如何将写好的HBuilder引入到我们的 ...

  4. android studio多渠道多包名多apk打包

    转自  利用 Android Studio 和 Gradle 打包多版本APK 搬砖的道路上,经常会有各种不同的需求,比如今天就碰到过一个打包版本的apk的要求, 比如一个apk给多个客户使用,如张三 ...

  5. 在Android studio中用gradle打 jar 包(Mac下)

    这两天公司要重构项目,以前的项目在eclipse上,准备迁移到Android studio上,需要对项目打包,于是我学习了Android studio中gradle打包的内容.我在公司用的Mac,在家 ...

  6. android studio 使用gradle 导出jar包,并打包assets目录

    警告:本文年久失修. 随着android studio的升级 ,gradle的升级,严格按照本文的代码去做可能不会成功,希望依然可以作为解决问题的思路. 最近项目在做一个sdk,供别的开发者使用,所以 ...

  7. [转]--android studio 使用gradle 导出jar包,并打包assets目录

    转自: http://www.cnblogs.com/wuya/p/android-studio-gradle-export-jar-assets.html   最近项目在做一个sdk,供别的开发者使 ...

  8. Android studio下gradle Robolectric单元测试配置

    android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...

  9. Android Studio :Android Studio 与 Gradle 深入【二】

    转载:http://www.apkbus.com/forum.php?mod=viewthread&tid=255063&extra=page%3D2%26filter%3Dautho ...

随机推荐

  1. 定时器——Cocos2d-x学习历程(十一)

    1.定时器 利用场景.层和精灵等游戏元素,我们可以构建游戏的框架,但是此时的游戏仍然是静止不动的.在一切游戏中,游戏的状态都会随着时间的流逝而改变,同时我们还需要定时进行一些逻辑判断,例如鱼和子弹的碰 ...

  2. JPA 2.1实例(hibernate 实现)

    1.环境准备 1)java se 7 2)maven 3 3)mysql database 2.创建数据库和表结构 首先创建数据库.创建数据库脚本如下: create database jpa; 创建 ...

  3. markdown流程图

    markdown流程图 markdown流程图 markdown流程图语法:https://github.com/adrai/flowchart.js 定义元素阶段的语法是 tag=>type: ...

  4. mysql函数操作(2)

    <?php $dbh = new PDO('mysql:dbname=testdb;host=localhost', 'mysql_user', 'mysql_pwd'); $dbh->s ...

  5. codeforces 659D . Bicycle Race 几何

    题目链接 对相邻的三个点叉积判断一下就好. #include <iostream> #include <vector> #include <cstdio> #inc ...

  6. MYSQL 数据表备份

    方法: mysqldump -uuser_name -p db_name table_nameList >save_file_path 例子: 备份分studio数据库的student 表 my ...

  7. SQL Server 查看数据页面

    第一步: 找到表的第一页dbcc ind(db_name,table_name,-1); 例子. dbcc ind(studio,person,-1);# pageFID  是文件号   pagePI ...

  8. Umbraco安装权限问题

    当安装或升级,甚至是使用Umbraco时,如果出现一些莫名其妙的问题. 估计都是权限出了问题,用心参考下文: https://our.umbraco.org/documentation/Getting ...

  9. 如何在C++中获得完整的类型名称(RTTI的typeid在不同平台下有不同的输出值表达,自建类改进了RTTI丢失的信息)

    Wrote by mutouyun. (http://darkc.at/cxx-get-the-name-of-the-given-type/)   地球人都知道C++里有一个typeid操作符可以用 ...

  10. BZOJ 1179 [Apio2009]Atm(强连通分量)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1179 [题目大意] 给出一张有向带环点权图,给出一些终点,在路径中同一个点的点权只能累 ...