开发人员或者测试人员经常需要将测试的内容与生产上的内容对比,用于做一些确认,可是通常情况下在一部手机上不能同时安装测试包与生产包,因为它们的application id 都是一样的,这是android系统的规定。为了达到这个目的,可以通过应用gradle灵活的配置方式来实现,通常有两种实现方式:
1、多渠道打包
通过Product Flavors可以创建不同的产品渠道版本,但每个产品渠道都会有对应的两个构建版本,debug和release,也就是说如果配置了两个Flavor,a和b,则打包时将有四个选择,aDebug, aRelease, bDebug, bRelease, 这当然可以达到我们的目的,不过我个人觉得这种方式有点杀鸡用牛刀的感觉,没这个必要。
2、配置applicationIdSuffix
这种方式是在 BuildTypes 代码块里面配置一个id的后缀,让debug与release版本的 application id 区别开来,这样用最简单的配置就能达到我们的目的。由于两个id都不一样,当然就可以同时装在一台手机上了。下面就来看看具体要怎么配置。
通常新建的项目 buildTypes代码块是像这个样子的:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
现在加上一个debug代码块,并在其中配置一下applicationIdSuffix属性,如下:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
// 在applicationId后面添加了一个后缀形成了debug的包名,与release区分开来
// release版本的applicationId就是defaultConfig里面的applicationId,不需要额外配置
applicationIdSuffix '.abc'
}
}
这里为debug版本中的 application id 添加了一个后缀,“.abc”,这个后缀是在defaultConfig里面的applicationId的基础上添加的,我没有在release版本中配置这个参数,所以release版本默认就是那个id。
为了方便打包,也在这里配置上签名,如:
//配置签名,注意:此代码块必须放在"buildTypes"代码块的上面,不然会找不到签名配置
signingConfigs {
// debug {
// debug 版本可以不配置签名文件,将默认使用系统自带的签名文件,
// win7系统在这里:C:\Users\Huangming\.android\debug.keystore,其中的 Huangming 是我在win7上的用户名
// 当然,如果你想配置的话也可以像下面的release版一样配置一下即可
// }
release {
// 签名文件放在app根目录下
storeFile file("../app/keystore.jks")
storePassword "123456"
keyAlias "aaa"
keyPassword "123456"
// 以上几个密码都是在生成 keystore.jks 文件时自己设置的
// 生成的方式:Build-->Generate Signed Bundle/APK...
}
}
同时在 buildTypes 中应用这个签名:
buildTypes {
release {
// 签名配置
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
// 在applicationId后面添加了一个后缀形成了debug的包名,与release区分开来
// release版本的applicationId就是defaultConfig里面的applicationId,不需要额外配置
applicationIdSuffix '.abc'
}
}
到此为止就已经可以打出两个不同appid的包了,不过光这样打出两个包没什么意义,要根据不同版本设置一些不同的参数才有实用意义,比如测试环境与生产环境的地址是不同的,这是最重要的,又比如测试包的app_name要改一下,才好区分,app的icon也要换一张也更好区分,某些内容也可以不一样。
下面来动态配置一下app_name,生产环境及测试环境的地址,完整的配置如下:
// 配置编译类型
// 重点是配置applicationId的后缀,使得两个版本的applicationId不一样,这样两个版本的apk就可以装在同一台手机上
buildTypes {
debug {
// 在applicationId后面添加了一个后缀形成了debug的包名,与release区分开来
// release版本的applicationId就是defaultConfig里面的applicationId,不需要额外配置
applicationIdSuffix '.abc'
//签名配置
// 可以不配置,直接使用系统自带的签名文件
// signingConfig signingConfigs.debug
// 动态配置在AndroidManifest.xml中的app名称
// 注意:这样配置的话要将AndroidManifest.xml中的 app_name 注释掉,不然会报名字重复的错误
resValue "string", "app_name", "测试包"
// 动态配置测试环境base_url,如:http://www.com.abc.degbug
// 在java代码中用 BuildConfig.BASE_URL 来获取从这里设置进去的 base url
buildConfigField "String", "BASE_URL", "\"http://www.com.abc.degbug\""
}
release {
// 签名配置
signingConfig signingConfigs.release
// 动态配置在AndroidManifest.xml中的app名称
// 注意:这样配置的话要将AndroidManifest.xml中的 app_name 注释掉,不然会报名字重复的错误
resValue "string", "app_name", "生产包"
// 动态配置生产环境base_url,如:http://www.com.abc.release
// 在java代码中用 BuildConfig.BASE_URL 来获取从这里设置进去的 base url
buildConfigField "String", "BASE_URL", "\"http://www.com.abc.release\""
// 为了看日志,把debug开关打开
debuggable true
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
有两个地方要注意一下:
1、 用 resValue "string", "app_name", "测试包"
这种方式动态配置了 app_name 之后,一定要将AndroidManifest.xml中的 app_name 注释掉,不然会报名字重复的错误。
2、 用 buildConfigField "String", "BASE_URL", "\"http://www.com.abc.release\""
这种方式动态配置生产和测试环境的地址, 需要在java代码中用 BuildConfig.BASE_URL
来获取
也可用另一种方式来动态配置两个版本的资源,即通过 sourceSets 指定资源目录,没有特别指定的话就在app/src/main中找资源,如果debug版本要用到不同的资源,就在 app/src 目录下新建一个名字为 “debug” 的文件夹, 这个文件夹与 “main”的结构一致,只要将其中的不同部分列出来就可以了。比如我用了不同的icon,还将MainActivity中的 hello world做了区别对待。如下图所示:
为了看到配置的效果,在MainActivity中打印出了服务器的url
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 看下是怎么取baseUrl的
Log.d("base_url = ",BuildConfig.BASE_URL);
}
}
动态显示 MainActivity中的“hello world”
最后来看下效果图:
桌面上能到两个版本的app了,可以看到logo和应用的名字都不一样了。再点进去看下里面的内容
里面的内容也区别显示了。再看看打印出来的url:
测试包
生产包
没问题,都按预期打印出了各自配置的url。
接下来看看appId
测试包
到此,我们配置的这几项都完美的实现了。
###最最后,上源码,如果有什么不清楚的把源码下下来跑一下:
demo源码:https://github.com/MingHuang1024/ConfigApplicationId
由于水平有限,如果文中存在错误之处,请大家批评指正,欢迎大家一起来分享、探讨!
博客:http://blog.csdn.net/MingHuang2017
GitHub:https://github.com/MingHuang1024
Email: [email protected]
微信:724360018