现状

工作项目里,一开始接入了穿山甲的广告SDK,用walle生成多个渠道的apk

后来要接入魅族的登录系统和广告,魅族和穿山甲用到的jar包有冲突,就不能全放在一个项目里,同事将整个项目copy了一份,在新的项目里移除穿山甲sdk,接入魅族,目录结构是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
proj.android
├── app
│   └── src
│ └── main
├── gradle
├── ...
└── settings.gradle

proj.android-flyme
├── app
│   └── src
│ └── main
├── gradle
├── ...
└── settings.gradle

这么做带来的坏处是不好维护,改什么都要改两个工程,很不合理。
最近又要接入华为的SDK,就想着用GradleproductFlavor将项目重构一下,合并到一个工程,后续接其他渠道也方便一点。

productFlavor

安卓项目使用Android Studio开发,Gradle构建。Gradle提供了productFlavor,通过配置不同flavor的参数,生成和flavor相关的task,实现工程参数化构建。用来做多渠道打包非常合适。

实现

  1. 首先,在主工程中,抽取出穿山甲相关资源和初始化代码抽取出来,放在src下的bu文件夹。Application类里要初始化广告,而每个广告初始化代码不一样,就不能放在main目录下,main文件夹的代码类名如果和flavor文件夹下的类名相同,代码无法整合,会报错。
  2. 然后,将魅族相关的相关的资源放在meizu文件夹下,因为魅族需要单独配置AndroidManifest.xml文件,就将和main中不一样,需要添加的配置放在meizu文件夹下AndroidManifest.xml。此时的目录结构是这样的:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    proj.android
    ├── app
    │   ├── build.gradle
    │   ├── libs
    │   │   ├── BaiduLBS_Android.jar
    │   │   ├── ...
    │   │   └── bugly_crash_release.jar
    │   └── src
    │   ├── bu
    │   │   ├── java
    │   │   │   └── com.fanle.majiang
    │   │   │      ├── manager
    │   │   │      │ └── TTAdManagerHolder.java
    │   │   │   ├── App.java
    │   │   │   └── BUBridge.java
    │   │   └── libs
    │   │   └── open_ad_sdk.aar
    │   ├── main
    │   │   ├── AndroidManifest.xml
    │   │   ├── java
    │   │   │   └── com.fanle.ddz
    │   │   ├── jniLibs
    │   │   │   └── armeabi
    │   │   │   ├── libBugly.so
    │   │   │   └── libwtcrypto.so
    │   │   ├── libs
    │   │   └── res
    │   └── meizu
    │   ├── AndroidManifest.xml
    │   ├── java
    │   │   └── com.fanle.majiang
    │   │   ├── App.java
    │   │   ├── FlymeBridge.java
    │   │   └── manager
    │   │   └── TTAdManagerHolder.java
    │   └── libs
    │   ├── ... 魅族sdk相关lib
    │   └── windAd-2.13.1.jar
    ├── build.gradle
    └── settings.gradle
  3. 修改build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
android {
...
sourceSets {
// 项目里默认使用穿山甲广告,因此特定渠道需要配置sourceSets,指定将bu文件夹的代码打进包
jinli {
java.srcDirs =['src/bu/java']
}
baidu {
java.srcDirs =['src/bu/java']
}
qihu {
java.srcDirs =['src/bu/java']
}
meizu {
java.srcDirs =['src/meizu/java']
}
}
productFlavors {
// 不同flavor配置不同的channel_id
jinli {
manifestPlaceholders = [channel_id : "2001"]
}
baidu {
manifestPlaceholders = [channel_id : "2009"]
}
qihu {
manifestPlaceholders = [channel_id : "2009"]
}
meizu {
// 魅族包名后缀要加.mz 需要单独配置applicationId
manifestPlaceholders = [channel_id : "2014"]
applicationId "com.fanle.flqyddz.mz"

}
}
...
}
// 依赖配置,gralde DSL支持(flavorName + Implementation)指定特定渠道的依赖项
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
baiduImplementation fileTree(include: ['*.jar','*.aar'], dir: 'src/bu/libs')
qihuImplementation fileTree(include: ['*.jar','*.aar'], dir: 'src/bu/libs')
meizuImplementation fileTree(include: ['*.jar','*.aar'], dir: 'src/meizu/libs')
implementation ...
}
  1. 编译
    这时跑一次./gradlew tasks --all查看所有任务,完成。
1
2
3
4
5
6
app:assembleBaiduDebug
app:assembleBaiduRelease

...
app:assembleMeizuDebug
app:assembleMeizuRelease

遇到的问题

在开发过程中,不同flavor如何使用android-studio的代码提示?

Build Variants中配置Active Build Variant

参考

  1. https://developer.android.com/studio/build/build-variants
  2. https://juejin.im/post/5cdbf5e3e51d45473d10ff11