Gradle多渠道代码

Android

一套代码衍生多套代码,打包不同的APK

当遇到需求,一套代码根据不同的客户打包成不同的logo或者不同的UI风格时,Android Studio中搭配gradle,使用productFlavors可以很好解决。
buildType也可以,但是一般处理的是编译配置。

常见的几种情况:

  • 资源文件assets、res,替换logo、图片、strings
  • AndroidManifest文件
  • java类文件

注意:资源文件、AndroidManifest文件在编译都可以使用main目录里的资源,因为他们是合并、替换或者覆盖;但是java文件必须在每个flavor中存在,main目录则不能存有,会报错,因为java类只能是唯一。

异常

1
2
3
4
5
1.All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
解决方法:defaultConfig{}加入flavorDimensions "default"

2.Duplicate class
解决方法:去掉main中重复的java类

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 多渠道
productFlavors {
system {

}
normal {

}
}
// 搭配productFlavors,指定资源
sourceSets {
system {
manifest.srcFile 'src/main/AndroidManifest_system.xml'
}
normal {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}

资源

简单的资源替代

替换字符串,在生成的BuildConfig类中可以找到。这种方法只适用少数的替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
productFlavors {
A {
// 替换字符串变量
buildConfigField("String", "name", "A")
// 替换资源字符串:R.string.type
resValue("string", "type", "A")
}
B {
buildConfigField("String", "name", "B")
resValue("string", "type", "B")
}
C {
buildConfigField("String", "name", "C")
resValue("string", "type", "C")
}
}

多渠道资源替换

创建多个flavor时,指向对应的资源目录:该资源目录在编译时,会与main里面的资源目录进行合并或者替换。

  • 合并
    如strings.xml,先合并main和当前flavor文件里资源;遇到id名相同时,则会用flavor的资源替换带main里面的资源。

  • 替换
    如assets、图片名字相同时,会被flavor的资源文件替换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
productFlavors {
A {
}
B {
}
}
// 两种写法,可以指定main里面的资源路径
sourceSets{
A.res.srcDirs=['src/main/res-a']
B.res.srcDirs=['src/main/res-b']
C.res.srcDirs=['src/main/res-c']
}
sourceSets {
A {
res.srcDirs = ['src/main/res-a']
}
B {
res.srcDirs = ['src/main/res-b']
}
C {
manifest.srcFile 'src/main/AndroidManifest_c.xml'
res.srcDirs = ['src/main/res-c']
}
}

或者创建与main同级的目录,表示一个flavor
gradle多渠道资源

AndroidManifest

该文件多渠道与资源文件多渠道有些类似,但是它是合并节点的形式。

默认的main里面有一个AndroidManifest文件,编译时的flavor也存在另外一个AndroidManifest,则会合并,根据节点tools:node配置,判断是否覆盖(replace)或者是合并(merge)等等,默认是merge。

1
2
3
4
5
6
7
8
<activity android:name=".MainActivity"
tools:node="merge">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

有时多个AndroidManifest时,修改flavor,但是没有达到效果,则要查看是否是tools:node配置的原因。

java文件

java文件比较特殊,如果想对文件A.java进行多渠道,需要去掉main里面的文件的A.java,然后在其他所有的flavor里加入A.java。这样flavor多的时候,修改A中公共的代码部分比较麻烦,目前还没好的办法。

谢谢老板,请尽情用红包来蹂躏我吧!!!
0%