####资源文件个性化处理
res目录下的都算资源文件(layout、values、drawable、mipmap)
-
在build.gradle中定义productFlavors
android { compileSdkVersion 23 buildToolsVersion "24.0.2" defaultConfig { applicationId "com.atearsan.multiflavors" minSdkVersion 14 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes {...} productFlavors { free { } pro { } } }
-
(在src目录下)创建与productFlavors对应的文件夹
-
将个性化处理的资源文件放到productFlavors对应的资源目录中(没有资源目录就按照main/res的结构创建)
-
资源文件个性化处理规则
命名要一样
文件路径要一样
比如productFlavors-pro的app_name要改成"MultiFlavors-PRO", 就在pro下创建strings.xml, 然后添加<string name="app_name">MultiFlavors-PRO</string>就好了
![](http://7xqmjb.com1.z0.glb.clouddn.com/2016091810427截图 2016-09-18 16时57分25秒.png?imageView2/2/w/900)
####AndroidManifest.xml内容个性化处理
- 新增属性 (新增的属性按照正常的写法就好了)
<activity android:name=".view.activity.ProActivity" />
- 覆盖main/AndroidManifest.xml中的属性 (比如覆盖
meta-data
的值)
文字不好描述, 直接看图片对比吧. ![](http://7xqmjb.com1.z0.glb.clouddn.com/2016091866407截图 2016-09-18 17时32分55秒.png?imageView2/2/w/1100)
AndroidManifest.xml内容的合并, 关键是tools:replace的使用. 更多内容参考: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger
####java文件性化处理
java文件处理起来会麻烦很多, 而且不适合项目大范围的修改. 因为改起来比较累 :(假如现在`main`中有一个java类:NextActivity.class, 现在要改成在`pro`中toast提示"pro", 在`free`中toast提示"free".
1.把NextActivity.class复制到free
和pro
对应的包路径下 (包路径保持一致)
2.删除main
中的NextActivity.class类. (不删除的话, 编译的时候会提示NextActivity类重复)
3.在free
和pro
中分别实现自己需要的逻辑
首先, 我们要弄懂Android程序中
applicationId
和packageName
的区别.简单粗暴的理解,
packageName
是我们能看到的程序的资源文件的路径. 比如:com.atearsan.multiflavors, 这个就是程序的包结构, 每个类的第一句是package com.atearsan.multiflavors.view.activity
. 引用某个类的时候会有一句import com.atearsan.multiflavors.R
.applicationId
是APK的唯一标识, 在Android系统中, applicationId
才代表一个唯一的应用. 创建一个project的时候, applicationId
默认就是我们指定的包结构路径. 可以在build.gradle
中找到. 通过代码获取到的packageName就是applicationId
, 但是反编译APK就会发现看到的目录结果跟applicationId
不一致, 而是我们编写代码的时候的目录结构.所以, 本段内容的标题中'包名'实际是指
applicationId
. 我们一般说一份代码发布多个版本的APK, 修改的也是applicationId
.注意: 程序代码获取到的packageName实际上是
applicationId
, 所以第三方服务(比如各种推送、各种分享、各种登录)要在AndroidManifest.xml
中配置包名的时候也是指applicationId
android {
compileSdkVersion 23
buildToolsVersion "24.0.2"
defaultConfig {
//applicationId "com.atearsan.multiflavors" // 默认值. 改成在productFlavors中定义
minSdkVersion 14
targetSdkVersion 23
//versionCode 1 // 改成在productFlavors中定义
//versionName "1.0"
}
buildTypes {...}
productFlavors {
free {
applicationId "com.free.xx.oo"
versionCode 1
versionName "v1.0"
}
pro {
applicationId "com.atearsan.multiflavors.pro"
versionCode 2
versionName "v1.1"
}
}
}
####依赖库(lib)及混淆个性化处理 android { buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } productFlavors { free { applicationId "com.free.xx.oo" versionCode 1 versionName "v1.0" } pro { applicationId "com.atearsan.multiflavors.pro" versionCode 2 versionName "v1.1" proguardFiles 'proguard-rules-pro.pro' // 混淆个性化处理 } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' proCompile 'com.android.support:appcompat-v7:23.4.0' // 依赖库个性化处理 }
####demo源码 (git.osc) http://git.oschina.net/atearsan/MultiFlavorsDemo
####参考内容
如何使用Gradle构建不同版本的app?
Manifest Merger
android基础:applicationId与packageName的区别
[Android] 应用的包名:ApplicationId vs PackageName
来源:oschina
链接:https://my.oschina.net/u/94055/blog/748420