QQ群288567073

微信订阅号见文末二维码

荔枝FM手机客户端搜索“挨踢脱口秀”订阅即可

视频汇总首页:http://edu.51cto.com/lecturer/index/user_id-4626073.html

======================================

在项目开发过程中,经常会有需要打包不同版本的 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 的原因。

长按下方二维码就可以识别关注


更多相关文章

  1. Android(安卓)Studio 设置自动配置git忽略
  2. Android实现3秒钟自动关闭界面
  3. Open Core 上层代码结构
  4. android 使用uinput模拟输入设备的方法
  5. python服务器与android客户端socket通信实例
  6. Android中判断手机是否联网实例
  7. android 超简单处理国际化
  8. Android(安卓)okhttp3中的坑
  9. Android培训班(70)Dex文件里类定义dvmDefineClass

随机推荐

  1. Android开机广播和关机广播
  2. Android中Handler Runnable与Thread的区
  3. 教你配置安卓开发环境!(附带开发通讯教程)
  4. Android-缓存数据保存-通用方法
  5. Android正确关闭线程
  6. Android(安卓)渐变色沉浸式状态栏
  7. 关于Base64解码和编码报错的问题
  8. Android幻灯片式图片浏览器
  9. Android(安卓)Studio实现Service AIDL
  10. Ubuntu 下用 Eclipse 编译调试 Android(