<p>相信大家的项目用上gradle都已经很久了,但用得如何呢?这里分享一下我的gradle脚本,大部分都是去年6月左右就开始用上的,有一部分比如签名的安全保存则是最近才自己动手,做了令自己觉得还不错的方案。</p>
module类型的区分
科普小结,可能有些同学不太明白Java library module和Android library module是怎么区分的,其实就是个plugin的区别,在module的build.gradle中:
Android application module:
1
|
apply
plugin:
'com.android.application'
|
Android library module:
1
|
apply
plugin:
'com.android.library'
|
Java library module:
版本号管理
如果只有一个application module还好,如果我们有多个module怎么办呢?每次改版本号累不累?
解决方案就是在root里申明全局变量,可以在单独的gradle里(比如新建一个dependency.gradle)申明然后apply from引用进来,或者直接定义在root的build.gradle中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
project.ext {
applicationId =
"com.xxx"
buildToolsVersion =
"23.0.2"
compileSdkVersion =
23
minSdkVersion =
14
targetSdkVersion =
23
versionCode =
1
versionName =
"1.0.0"
abortOnLintError =
false
checkLintRelease =
false
useJack =
false
abortOnLintError =
false
javaVersion = JavaVersion.VERSION_1_8
...
}
|
在子module里面则使用rootProject.ext去进行引用:
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
|
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId rootProject.ext.applicationId
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
multiDexEnabled
true
}
compileOptions {
sourceCompatibility rootProject.ext.javaVersion
sourceCompatibility rootProject.ext.javaVersion
}
packagingOptions {
exclude
'LICENSE.txt'
exclude
'META-INF/DEPENDENCIES'
exclude
'META-INF/ASL2.0'
exclude
'META-INF/NOTICE'
exclude
'META-INF/LICENSE'
}
lintOptions {
abortOnError rootProject.ext.abortOnLintError
checkReleaseBuilds rootProject.ext.checkLintRelease
quiet
true
ignoreWarnings
true
disable
'InvalidPackage'
disable
'OldTargetApi'
}
...
}
|
依赖管理
那么多第三方库的引用,在多个module里引用,修改起版本号来好辛苦,万一有一个漏改了(比如gson)结果导致了异常行为,搞不好查原因查个半天,结果摔键盘竟然是版本号导致的。
so,和上节类似,我们需要统一定义依赖:
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
46
47
48
49
|
def daggerVersion =
"2.0.2"
def retrofitVersion =
"2.0.0-beta4"
def supportVersion =
"23.2.1"
def rxBindingVersion =
'0.4.0'
def leakCanaryVersion =
"1.3.1"
def blockCanaryVersion =
'1.1.4'
project.ext {
...
libSupportAppcompat =
"com.android.support:appcompat-v7:${supportVersion}"</span></div><div class="line"> libSupportDesign = <span class="string">"com.android.support:design:${supportVersion}"
libSupportRecyclerview =
"com.android.support:recyclerview-v7:${supportVersion}"</span></div><div class="line"> libSupportV4 = <span class="string">"com.android.support:support-v4:${supportVersion}"
libRxAndroid =
"io.reactivex:rxandroid:1.1.0"
libRxJava =
"io.reactivex:rxjava:1.1.1"
libEventBus =
"org.greenrobot:eventbus:3.0.0"
libJavaxAnnotation =
"javax.annotation:jsr250-api:1.0"
libGson =
"com.google.code.gson:gson:2.4"
libRetrofit =
"com.squareup.retrofit2:retrofit:${retrofitVersion}"</span></div><div class="line"> libRetrofitConverterGson = <span class="string">"com.squareup.retrofit2:converter-gson:${retrofitVersion}"
libRetrofitAdapterRxJava =
"com.squareup.retrofit2:adapter-rxjava:${retrofitVersion}"</span></div><div class="line"> libOkHttpLoggingInterceptor = <span class="string">"com.squareup.okhttp3:logging-interceptor:3.0.0-RC1"</span></div><div class="line"></div><div class="line"> libDagger = <span class="string">"com.google.dagger:dagger:${daggerVersion}"
libDaggerCompiler =
"com.google.dagger:dagger-compiler:${daggerVersion}"</span></div><div class="line"></div><div class="line"> libGlide = <span class="string">"com.github.bumptech.glide:glide:3.7.0"</span></div><div class="line"></div><div class="line"> libRxBinding = <span class="string">"com.jakewharton.rxbinding:rxbinding:${rxBindingVersion}"
libRxBindingSupportV4 =
"com.jakewharton.rxbinding:rxbinding-support-v4:${rxBindingVersion}"</span></div><div class="line"> libRxBindingAppcompatV7 = <span class="string">"com.jakewharton.rxbinding:rxbinding-appcompat-v7:${rxBindingVersion}"
libRxBindingDesign =
"com.jakewharton.rxbinding:rxbinding-design:${rxBindingVersion}"</span></div><div class="line"> libRxBindingRecyclerview = <span class="string">"com.jakewharton.rxbinding:rxbinding-recyclerview-v7:${rxBindingVersion}"
libRealm =
"io.realm:realm-android:0.87.5"
debugDependencies = [
leakCanary:
"com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}"</span>,</div><div class="line"><span class="symbol"> blockcanary:</span> <span class="string">"com.github.moduth:blockcanary-ui:${blockCanaryVersion}",
]
releaseDependencies = [
leakCanary:
"com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}"</span>,</div><div class="line"><span class="symbol"> blockcanary:</span> <span class="string">"com.github.moduth:blockcanary-no-op:${blockCanaryVersion}",
]
}
|
这里也可以根据个人喜好把版本号也全都抽出去,我个人的实践原则是除非引用超出1处,否则还是定义在一起。
module中使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
dependencies {
compile fileTree(
include: [
'*.jar'],
dir:
'libs')
...
apt rootProject.ext.libDaggerCompiler
compile rootProject.ext.libDagger
compile rootProject.ext.libRxJava
compile rootProject.ext.libRxAndroid
compile rootProject.ext.libRxBinding
compile rootProject.ext.libGlide
provided rootProject.ext.libJavaxAnnotation
compile rootProject.ext.libSupportAppcompat
compile rootProject.ext.libSupportDesign
compile rootProject.ext.libSupportRecyclerview
compile rootProject.ext.libSupportV4
debugCompile rootProject.ext.debugDependencies.leakCanary
releaseCompile rootProject.ext.releaseDependencies.leakCanary
debugCompile rootProject.ext.debugDependencies.blockCanary
releaseCompile rootProject.ext.releaseDependencies.blockCanary
}
|
这里我还特地为一些debug和release compile不同包的定义了2个map,见leakCanary和blockCanary引用。
签名管理
签名是一个很敏感的东西,只要有了签名文件和对应的密码信息,就能轻易反编译修改源码然后再签名进行发布,因此如何保存这些敏感信息是很重要的。
在我的个人实践中,主要做了这么几点:
local.properties定义keystore信息文件路径:
1
|
keystore.props.file=../keystore.properties
|
keystore.properties保存keystore信息:
1
2
3
4
|
store=../buildsystem/release.jks
alias=xxx
storePass=xxx
pass=xxx
|
buildsystem下保存了:
1
2
3
4
|
$ ls
ci.gradle
debug.keystore
release.jks
|
application module的signingConfigs:
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
|
signingConfigs {
def Properties localProps =
new Properties()
localProps.load(
new FileInputStream(file(
'../local.properties')))
def Properties keyProps =
new Properties()
if (localProps[
'keystore.props.file']) {
keyProps.load(
new FileInputStream(file(localProps[
'keystore.props.file'])))
}
else {
keyProps[
"store"] =
'../buildsystem/debug.keystore'
keyProps[
"alias"] =
'android'
keyProps[
"storePass"] =
'androiddebugkey'
keyProps[
"pass"] =
'android'
}
debug {
storeFile file(keyProps[
"store"])
keyAlias keyProps[
"alias"]
storePassword keyProps[
"storePass"]
keyPassword keyProps[
"pass"]
}
release {
assert localProps[
'keystore.props.file'];
storeFile file(keyProps[
"store"])
keyAlias keyProps[
"alias"]
storePassword keyProps[
"storePass"]
keyPassword keyProps[
"pass"]
}
}
|
Java8支持
对Android的module
1
2
3
4
5
6
7
8
|
apply
plugin:
'me.tatarka.retrolambda'
android {
compileOptions {
sourceCompatibility rootProject.ext.javaVersion
sourceCompatibility rootProject.ext.javaVersion
}
}
|
对Java的module:
1
2
|
sourceCompatibility =
1.8
targetCompatibility =
1.8
|
Split APK
详细的可以看看Google的官方文档Apk Splits
我的使用:
1
2
3
4
5
6
7
8
|
splits {
abi {
enable
true
reset()
include
'armeabi',
'x86'
universalApk
false
}
}
|
大致来说,就是可以根据脚本的配置,将apk以abi、density进行分包。再也不用为了缩小包的体积而专门去只留下一个arm的jni文件夹了,想怎么分怎么分,搞不定哪天就要传一个x86的包了,而且有的模拟器也只支持x86。
当然如果市场能支持这些配置,那就更好了,用户下载apk的流量就小多了。
Module aar依赖
怎么能在使用aar依赖提升编译速度的同时,又能兼顾灵活性,随时可以修改源码呢?
解决方案就是module式aar依赖。
在你的library module目录下, 打开build/outputs/aar,是不是有aar文件(编译过后就会生成)?把它放到module目录下面,然后在build.gradle里面:
1
2
|
configurations.maybeCreate(
"default")
artifacts.add(
"default", file(
'lib_authorize-debug.aar'))
|
再把原来那些脚本给注释了,就搞定了。是不是特别简单?如果想再使用源码依赖,反注释一下就好了。
总结
本篇主要讲了开发阶段gradle的各种实践,下一篇是什么暂时我也没有想法,哈哈。
转自:http://blog.zhaiyifan.cn/2016/03/14/android-new-project-from-0-p2/