赞
踩
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
这里面的value是个可变的值,它之所以可变,是因为在build.gradle中的productFlavors 这个script block下给每个渠道商下的UNMENG_CHANNEL_VALUE赋了不同的值。
- <span style="font-size:14px;">productFlavors {
- wandoujia {}
- baidu {}
- productFlavors.all {
- flavor->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
- }
- }</span>
最好安装好gradle工具,配置好环境变量,然后在cmd或者android studio的控制台中输入以下命名:
gradle assemble ,assemble是个task,此外,还有assembleRelease,assembleDebug两个task可用,它们的作用分别是全部编译、
只编译release版和只编译debug版。
gradle assemble 执行后生成的apk:
gradle assembleRelease执行后生成的apk:
- <span style="font-size:14px;"> sourceSets {
- main {
-
- }
- }</span>
- <span style="font-size:14px;"> sourceSets {
- main {
- manifest.srcFile('MineManifest.xml')
- }
- }</span>
- <span style="font-size:14px;">Error:A problem was found with the configuration of task ':app:checkDebugManifest'.
- > File 'E:\android\androidwork2.0\GradleTest2\app\MineManifest.xml' specified for property 'manifest' does not exist.</span>
- <span style="font-size:14px;"> sourceSets {
- main {
- manifest.srcFile('/src/main/MineManifest.xml')
- }
- }</span>
这些资源路劲也是可以修改的:
- <span style="font-size:14px;"> sourceSets {
- main {
- manifest.srcFile('/src/main/MineManifest.xml')
- java.srcDir('java')
- res.srcDir('res')
- aidl.srcDir('java')
- }
- }</span>
- <span style="font-size:14px;"> sourceSets {
- main {
- manifest.srcFile('/src/main/MineManifest.xml')
- java.srcDir('hello')
- res.srcDir('haha')
- aidl.srcDir('hello')
- }
- }</span>
就会报一下类似错误:
<span style="font-size:14px;">Error:(13, 23) No resource found that matches the given name (at 'icon' with value '@mipmap/ic_launcher').</span>
应该还是资源找不到,加上绝对路径试试?是的,就可以了,内部不知道是怎么实现的,但加上绝对路劲确实可以解决这种问题。修改以后变成这样:
- <span style="font-size:14px;"> main {
- manifest.srcFile('/src/main/MineManifest.xml')
- java.srcDir('/src/main/helo')
- res.srcDir('/src/main/haha')
- aidl.srcDir('/src/main/hello')
- }</span>
- <span style="font-size:14px;"> sourceSets {
- main {
- manifest.srcFile 'AndroidManifest.xml'
- java.srcDirs = ['src']
- resources.srcDirs = ['src']
- aidl.srcDirs = ['src']
- renderscript.srcDirs = ['src']
- res.srcDirs = ['res']
- assets.srcDirs = ['assets']
- }
-
- instrumentTest.setRoot('tests')
- }</span>
一次生成过个渠道发布的不同UI的apk,这看起来很酷。所以我觉得这一章节是全文最有意思的地方。
创建build变量是很有用的,比如说你有这样的需求:debug版打印Log,release版不打印Log,怎么实现呢?
可做如下修改:
- <span style="font-size:14px;"> buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- resValue("string","DEBUG","false")
- }
- debug {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- resValue("string","DEBUG","true")
- }
- }</span>
- <span style="font-size:14px;">public final class BuildConfig {
- public static final boolean DEBUG = Boolean.parseBoolean("true");
- </span>
所以在代码中使用的时候,只需要这样:
- <span style="font-size:14px;"> if(BuildConfig.DEBUG){
- Log.d("hello","debug");
- }</span>
android studio中默认的build type 有两种:debug和release,想像3.1展示的那样,如果这些默认的build type满足不了项目的需求的时候,你可以自定一个build type,所有你需要做的就是新建一个type,想下面这样:
- <span style="font-size:14px;">staging {
- applicationIdSuffix ".staging"
- versionNameSuffix "-staging"
- buildConfigField "String", "API_URL",
- "\"http://staging.example.com/api\""
- }</span>
把它添加到buildTypes { }中,添加好以后,你可以在android studio左下的build Variants菜单下选择对应的staing,然后就可以编译出使用staging作为build type的apk,如图:
图中,Build Variant是可选则的,你点击它看一下就会明白一切。此外,你还可以使用命令生成apk:gradle assemblestaging
执行这条命令的前提是你的系统中已经安装了gradle工具,我还是推荐你安装一个gradle,通过敲命令你更容易理解gradle工作的过程。关于为什么可以执行这条命令,这里还想啰嗦一下,staging毕竟使我们自定义的,gradle怎么会知道它存在呢?是的这就是自动创建task,gradle会根据配置文件自动给你生成需要的task,你如你有一个staging的build type,gradle就会生成一个assemblestaging的task,如果同时,你有一个flavor叫做baidu,gradle还会给你生成一个assedblebaidu的task,同时你还可以组合他们,比如:assemblebaidustaging,这里是不是开始领悟gradle的强大了?
此外,自定义build type时,你可以充分利用已有的版本,然后在它的基础上做一些修改,就像下面这样:
- <span style="font-size:14px;">android {
- buildTypes {
- staging.initWith(buildTypes.debug)
- staging {
- applicationIdSuffix ".staging"
- versionNameSuffix "-staging"
- debuggable = false
- }
- }
- }</span>
当你创建一个build type时,gradle会为你生成一个source set,默认的,它的目录和你build type的名字相同,但是它不会自动为你创建目录,你需要自己创建目录,你只需要在和main同级的目录下创建和build type名字相同的目录即可,这个目录结构和你原来的那个目录很相似,下图是添加staging后的目录结构示意图:
gradle这种强大的功能为你打开了一个新的世界,这使得你为不同的构建类型添加不同的代码,添加不同的资源成为可能。
资源的处理比较特殊,当你使用不同的source set时,Drawable和layout文件将会完全的覆盖main source set下的同名文件,但是value下的文件,比如string.xml就不是这样的,gradle合并的是内容而不是文件。一定要注意它合并的是内容,这很重要。比如,某个build type 的source set中有这样的string.xml:
- <span style="font-size:14px;"><resources>
- <string name="app_name">TypesAndFlavors STAGING</string>
- </resources></span>
main source set下的string.xml是这样:- <span style="font-size:14px;"><resources>
- <string name="app_name">TypesAndFlavors</string>
- <string name="hello_world">Hello world!</string>
- </resources></span>
那么使用main source set下的string.xml合并build type下的string.xml的内容,合并结果是这样的:
- <span style="font-size:14px;"><resources>
- <string name="app_name">TypesAndFlavors STAGING</string>
- <string name="hello_world">Hello world!</string>
- </resources></span>
给build type添加类文件时,要注意,这个过程是互斥的,就是说main source set下的java文件不能很buile type下的source set下的java文件相同,比如,如果staging 的source set和main source set下都有一个A.java,那么会暴错,gradle会认为你的一个类定义了两次。
manifest文件的合并和string.xml文件的合并类似,是文件内容的合并。因此,build type中的manifest文件不需要完全复制main下的manifest文件,只需要写出不同于main source set下的manifest的部分。
除了一次性生成多个productFlavors,和build type 类似,productFlavors也能生成自己的source set目录,这个目录也需要你自己区创建,名字和productFlavors声明的flavor名字相同即可。更进一步,这个目录和buile type的目录名字可以组合使用。比如,我在productFlovors下定义了一个名为baidu的flavor,定义了一个staging的build type,然后目录名就可以为baidustaging。
第一步:定义build type 和 product flavors 以及他们的sourceSets
这我们已经做过了,现在 直接把build.gradle贴出来:
- <span style="font-size:14px;">apply plugin: 'com.android.application'
-
- android {
- compileSdkVersion 23
- buildToolsVersion "23.0.3"
-
- defaultConfig {
- applicationId "com.konka.gradletest2"
- minSdkVersion 16
- targetSdkVersion 23
- versionCode 1
- versionName "1.0"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- resValue("string","DEBUG","false")
- }
- debug {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- resValue("string","DEBUG","true")
- dependencies {
-
- }
- }
- staging {
- applicationIdSuffix ".staging"
- versionNameSuffix "-staging"
- buildConfigField "String", "API_URL",
- "\"http://staging.example.com/api\""
- }
- }
- sourceSets {
- main {
- manifest.srcFile('/src/main/MineManifest.xml')
- java.srcDir('/src/main/helo')
- res.srcDir('/src/main/haha')
- aidl.srcDir('/src/main/hello')
- }
- baiduStaging {
- manifest.srcFile('/src/main/MineManifest.xml')
- java.srcDir('/src/main/helo')
- res.srcDir('/src/baiduStaging/haha')
- aidl.srcDir('/src/main/hello')
- }
- wandoujiaStaging {
- manifest.srcFile('/src/main/MineManifest.xml')
- java.srcDir('/src/main/helo')
- res.srcDir('/src/wandoujiaStaging/haha')
- aidl.srcDir('/src/main/hello')
- }
- }
- productFlavors {
- wandoujia {
- }
- baidu {
- }
- productFlavors.all {
- flavor->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
- }
- }
- }
-
- dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- testCompile 'junit:junit:4.12'
- compile 'com.android.support:appcompat-v7:23.3.0'
- }</span>
第二部:修改目录
看一下图就明白了:
第三步:修改资源
现在只把引用程序的图标和名字给替换掉,这里不多说,我想大家都会弄。其中标题在string.xml下,图标在mipmap-xxhdpi目录下,大家注意他们的合并方式,前面都讲过了。
第四步:生成apk
直接运行gradle assemblestaging
第五步: 签名并安装
第六步:成果展示:
baidu:
图标 界面
wandoujia:
图标 界面
多模块的工程就是在项目的根目录下有多个module,在android studio下这很简单:
比如就你现在有一个这样的工程:
你只需要做一件事::在你的工程上右键,选择新建mudole。
是的就这么简单,现在看看工程的样子:
是的,这个时候,settings.gradle中多了一项,他就是我们新加的module的名字,它其实就是工程顶层目录下的一个目录的名字。这个名字你可以随便改,module你也可以随便加。
添加一个java library时,需要修改module下的build.gradle,修改后看起来应该这样:
- <span style="font-size:14px;">apply plugin: 'java'
- dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- }</span>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。