动态配置LauncherActivity/根据不同资源文件生成apk
需求
1.同一份代码,采用三份不同的资源文件,生成三个不同的apk;
2.同一份代码,采用相同代码和资源文件,仅有LauncherActivity不同,生成两个apk;
经过一番查询,以上需求可以通过Gradle中配置ProductFlavors完美解决。
BuildVariants基本知识
标签meta-data是提供组件额外的数据用的,它本身就是一个键值对,可以自定义名称和值。它可以包含在以下组件当中:activity\application\service\receiver。
manifestPlaceholders的作用 :在build.gradle文件中定义字符串并将值映射到 AndroidManifest清单文件的指定位置.
1.AndroidMenifest.xml中添加meta-data
1 2 3
| <meta-data android:name="APP_CHANNEL" android:value="${APP_CHANNEL_VALUE}"/>
|
2.build.gradle(Moudle)中添加(以下两种写法相同)
1 2 3 4 5 6 7 8
| productFlavors{ eyewatch { manifestPlaceholders = [APP_CHANNEL: "eyewatch"] } ipremium { manifestPlaceholders = [APP_CHANNEL: "ipremium"] } echo { manifestPlaceholders = [APP_CHANNEL: "echo"] } }
|
1 2 3 4 5 6 7 8
| productFlavors { eyewatch {} ipremium {} echo {} productFlavors.all { flavor -> flavor.manifestPlaceholders = [APP_CHANNEL: name] } }
|
构建变体BuildType
当创建工程时,Android Studio会自动生成debug/release两种buildtype,我们可以根据自己定义生成更多的buildtype
productFlavors支持与 defaultConfig
相同的属性(defaultConfig
实际上属于 ProductFlavor
类)。这意味着,您可以在 defaultConfig {}
代码块中提供所有风味的基本配置,每种风味均可更改任何这些默认值。
buildType x productFlavor x flavorDimensions = 生成的APK数量
assemble命令简介
1 2 3 4 5 6 7 8
| ./gradlew assembleDebug 编译并生成Debug包,包含productFlavors下所有定义的产品或渠道包 ./gradlew assembleRelease 编译并生成Release包,包含productFlavors下所有定义的产品或渠道包 ./gradlew assembleProductARelease 编译并生成Release包,包含pProductA下所有定义的产品或渠道包 ./gradlew assembleProductADebug 编译并生成Debug包,包含pProductA下所有定义的产品或渠道包
|
flavor跟main的文件合并规则
①java中代码合并,如果有相同的文件是会报错重复错误的,所以main文件夹中,应该存放共有的代码,而flavor文件夹中存放自己所需要的独立的代码。
②res中资源的合并,优先级是flavor高于main,即flavor中资源会加入或覆盖main中资源。如果falvor渠道要求指定的icon和appName,则在special中res中替换到默认的icon,在string.xml中改正相应的appName即可。
需求1.同一份代码,不同资源文件
在/src中,main同级目录新建对应falvor名称的文件夹。各个falvor文件内目录应与main目录结构完全一致,需要替换的资源文件名字也要相同。如/eyewatch/drawable/bg.png 与 /main/drawable/bg.png。
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
| defaultConfig { applicationId "com.echo.settings" minSdkVersion 19 targetSdkVersion 22 versionCode 1 versionName "1.2" flavorDimensions "versionCode" //执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。 lintOptions { abortOnError false checkReleaseBuilds false }
buildTypes { debug { // 显示Log buildConfigField "boolean", "LOG_DEBUG", "true"
versionNameSuffix "-debug" minifyEnabled false zipAlignEnabled false shrinkResources false
android.applicationVariants.all { variant -> variant.outputs.all { outputFileName = "Settings_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk" } } } }
// 多渠道打包 productFlavors { echo {} eyewatch {} ipremium {} }
productFlavors.all { flavor -> flavor.manifestPlaceholders = [APP_CHANNEL_VALUE: name] }
|
需求2.同一份代码,不同LauncherActivity
在/src中main同级目录中创建对应flavor文件夹,复制一份manifest.xml文件。
将原LauncherActivity下 添加 tools:node=”merge”,Intent-filter中添加 tools:node=”remove”
1 2 3 4 5 6 7 8 9 10 11 12 13
| <activity android:name=".app.launcher.Launcher" android:launchMode="singleTask" android:exported="true" android:screenOrientation="landscape" tools:node="merge" > <intent-filter tools:node="remove"> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LEANBACK_LAUNCHER"/> </intent-filter> </activity>
|
在对应想要启动的Activity下设置即可。
1 2 3 4 5 6 7 8 9 10 11
| <activity android:name=".app.launcher.SimpleLaunch" android:exported="true" android:launchMode="singleTask" android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LEANBACK_LAUNCHER"/> </intent-filter> </activity>
|
meta-data
ProductFlavor
AndroidSourceSet
合并多个清单文件
使用gradle的productFlavors实现Android项目多渠道打包
Android Gradle manifestPlaceholders 占位符详解