Android中的Serializable、Parcelable">Android中的Serializable、Parcelable
888
2022-05-30
Gradle構建腳本使用Groovy來編寫。默認的構建文件名為build.gradle 。Gradle命令在構建時,會尋找一份名為build.gradle的文件,然后執行。
在android studio項目中,默認情況下,根目錄有一份build.gradle ,各個module也各有一份。
在android studio項目里的任意一份build.gradle文件里定義一個hello任務,執行gradle命令時,就會在這些build.gradle文件中尋找所有定義的hello任務,從根目錄開始逐個執行,如:
在根目錄的build.gradle文件中定義:
task hello { println 'Hello world root' }
1
2
3
在app module目錄的build.gradle文件中定義:
task hello { println 'Hello world app' }
1
2
3
在build.gradle所在目錄使用gradle命令運行這個task
juk@Juk-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q hello Hello world root Hello world app
1
2
3
也可以直接運行項目,然后在build的日志窗口可以看到輸出
Gradle構建腳本中的Project對象
Project對象是實現了org.gradle.api.Project接口的對象。在build.gradle這個腳本中, 我們就會使用Project對象與Gradle構建命令打交道。通過它,我們訪問很多Gradle提供的功能特性。
build.gradle文件與Project對象有一個一對一的關系。在構建初始化時,gradle會為每一個參與到構建中來的項目模塊(module)組裝一個Project對象,具體過程是這樣的:
首先,為本次構建,創建org.gradle.api.initialization.Settings實例。執行settings.gradle腳本中的內容,并對Settings對象進行配置。它主要聲明一些配置,用于實例化和配置參與構建的Project對象的層次。一個Settings對象對應于一份settings.gradle文件。這一步是在開始構建前完成的。
使用配置好的Settings對象創建Project實例的層次
最后,通過執行各個項目(module)的build.gradle配置各自的Project對象。執行的順序,默認情況是從父項目(父module)再到子項目(子module)。
build.gradle的組成
一般,一個項目(module)對應一份build.gradle腳本。我們會用build.gradle腳本去配置Project對象。所以 build.gradle的組成就是Project對象的組成。
Tasks
一個Project對象基本上就是Tasks對象的集合。每個task都執行一些基本的工作,如編譯類,運行單元測試,壓縮WAR包,生成JavaDoc。每個task都屬于某一個Project對象。Task對象是由TaskContainer對象負責創建的,在腳本中可以直接使用task的名字直接調用。在構建腳本中使用task關鍵字就可以聲明task了:
task helloTask task helloTask {} task helloTask(type:Delete) task helloTask(type:Delete){} // 創建hello1 task task(hello1) { println "Good morning!1" } // 創建hello2 task task('hello2') { println "Good morning!" } // 創建hello3 task tasks.create(name:'hello3') { println "Good afternoon!" }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上面這些聲明都是合法的
一個task是由一系列的行為對象組成的。當task被執行時,它們就會依次被執行。
給task hello2添加一個依賴
task hello1 { doLast { println 'Hello world 1' } } task hello2(dependsOn: 'hello1') { doLast { println 'Hello world 2' } }
1
2
3
4
5
6
7
8
9
10
11
上面這種方式還可以換成以下這種方式:
task hello2 { doLast { println 'Hello world 2' } } task hello1 { doLast { println 'Hello world 1' } } hello2.dependsOn hello1
1
2
3
4
5
6
7
8
9
10
11
12
13
依賴還可以這樣來寫:
task hello2 { doLast { println 'Hello world 2' } } task hello1 { doLast { println 'Hello world 1' } } hello2.dependsOn { tasks.findAll { taskIt -> taskIt.name.startsWith('hello1') } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
運行結果都是:
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q hello2 Hello world 1 Hello world 2
1
2
3
doLast的意思就是將這個task 行為放到task的行為列表的最后面。
project.ext.skipStage = 'Hello' task skipTask { doLast { println 'Hello world' } } // 當有這個skipStage屬性時才執行skipTask,沒有時跳過skipTask,因當前面有定義skipStage這個屬性,因此會執行skipTask skipTask.onlyIf{ project.hasProperty('skipStage') }
1
2
3
4
5
6
7
8
9
10
11
還可以通過拋異常的方式來跳過,如上面的代碼可以換成下面的來實現:
project.ext.skipStage = 'Hello' task skipTask { doLast { println 'Hello world' } } skipTask.doFirst { if(!project.hasProperty('skipStage')){ throw new StopExecutionException() } }
1
2
3
4
5
6
7
8
9
10
11
12
結果都是:
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q skipTask Hello world
1
2
3
在它要執行task之前,Gradle會經歷不同的階段。首先是配置階段,過后就是執行階段,這個階段它就會執行task的doFirst或doLast閉包里的代碼。
這里要給大家說明一下, 下面這種task的寫法是OK的:
task hello { println 'Hello world 1' } hello { println 'Hello world 2' }
1
2
3
4
5
6
7
結果:
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q hello Hello world 1 Hello world 2
1
2
3
4
Dependencies
依賴配置應該是大家最熟悉的了。最常見就是下面這些:
dependencies { // 只能在當前項目(module)使用 implementation 'group:name:version' // 共享 api 'group:name:version' // 單元測試 testImplementation 'group:name:version' // android測試 androidTestImplementation 'group:name:version' ... }
1
2
3
4
5
6
7
8
9
10
11
在腳本就是這樣配置的,它在Project對象中是由DependencyHandler對象管著的。
Repositories
指定外部依賴的源,就是告訴gradle去這個倉庫下載我們添加的依賴。
repositories { google() mavenCentral() }
1
2
3
4
指定自己的依賴倉庫,也是用這個
repositories { maven { url "http://repo.juk.com/maven2" } }
1
2
3
4
5
在腳本中配置的這些會用來配置在Project對象中的RepositoryHandler對象管著的。
如果你要上傳你壓縮包到maven倉庫,那么你可以在maven插件的uploadArchives task用repositories指定上傳位置
apply plugin: 'maven' // 要先把maven插件加進來,否則沒有uploadArchives任務 uploadArchives { repositories { mavenDeployer { repository(url: "http://repo.juk.com/maven2") } } }
1
2
3
4
5
6
7
8
Plugins
其實插件并沒有什么特殊之處,它就是一些task的集合,例如有些插件里有編譯的task,設置源文件的task設置等等。添加插件到項目中來其實就是為了擴充Project對象的能力,讓它能做更多事。android項目的build.gradle就會有如下的插件:
plugins { id 'com.android.application' id 'kotlin-android' }
1
2
3
4
一般來說插件有兩種類型:
一種是腳本插件,它是一構建腳本,會用于構建過程中。
另一種是二進制插件,它們是一些實現了插件接口的類,通過程序的方法來控制構建。
對應的,添加插件也有兩種方式:
從本地文件系統添加一份腳本
apply from: 'other.gradle'
1
添加二進制插件
plugins { id 'com.android.application' }
1
2
3
或
apply plugin: 'com.android.application'
1
首先在build.gradle的開頭引用我們的插件
apply plugin: HelloPlugin
1
然后在build.gradle找一個地方定義我們的插件,如文件末尾:
class HelloPlugin implements Plugin
1
2
3
4
5
6
7
8
9
10
11
12
如你所見,自定義的插件,需要實現Plugin接口,apply方法的參數,就是當前build.gradle腳本對應的Project對象,從我們定義里可以看出我們往Project對象里添加了一個task,名為myHelloTask,我們也可以通過傳進來的project對象去訪問它的東西,如定義的屬性。 我們來運行一下這個task:
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q myHelloTask Hello,My first plugin!
1
2
如何從build.gradle中獲得輸入?我們可以擴展Project對象,然后通過擴展后的對象來實現,具體如下:
apply plugin: HelloPlugin ... // step 2:使用插件擴展出來的屬性對象設置它的屬性值 myParameter.message = 'Halo Wo' class HelloPlugin implements Plugin
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
運行任務myHelloTask:
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q myHelloTask Halo Wo
1
2
3
注意:在Gradle的版本中已有很多標準插件,如編程語言插件:java ,scala,assembler, c,cpp
例如要引用CPP插件:
apply plugin: cpp
1
查看構建信息
查看Project對象的層次結構
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q projects ------------------------------------------------------------ Root project 'HelloWorld' ------------------------------------------------------------ Root project 'HelloWorld' +--- Project ':app' \--- Project ':houseware' To see a list of the tasks of a project, run gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
查看任務
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q tasks ------------------------------------------------------------ Tasks runnable from root project 'HelloWorld' ------------------------------------------------------------ Android tasks ------------- androidDependencies - Displays the Android dependencies of the project. signingReport - Displays the signing info for the base and test modules sourceSets - Prints out all the source sets defined in this project. Build tasks ----------- assemble - Assemble main outputs for all the variants. assembleAndroidTest - Assembles all the Test applications. build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildKotlinToolingMetadata - Build metadata json file containing information about the used Kotlin tooling buildNeeded - Assembles and tests this project and all projects it depends on. bundle - Assemble bundles for all the variants. clean - Deletes the build directory. ......
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
當然你也可以指定看某個項目的task,如houseware項目的task
juklinglee@JukLings-MacBook-Pro HelloWorld % /Users/juklinglee/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q :houseware:tasks ------------------------------------------------------------ Tasks runnable from project ':houseware' ------------------------------------------------------------ Android tasks ------------- androidDependencies - Displays the Android dependencies of the project. signingReport - Displays the signing info for the base and test modules sourceSets - Prints out all the source sets defined in this project. Build tasks ----------- assemble - Assemble main outputs for all the variants. assembleAndroidTest - Assembles all the Test applications. build - Assembles and tests this project. ......
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
查看所有屬性值
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q properties ------------------------------------------------------------ Root project 'HelloWorld' ------------------------------------------------------------ AGP_INTERNAL__MIN_PLUGIN_VERSION_CHECK_STARTED: true _internalAndroidGradlePluginDependencyCheckerRegistered: true allprojects: [root project 'HelloWorld', project ':app', project ':houseware'] android.enableJetifier: true android.useAndroidX: true ant: org.gradle.api.internal.project.DefaultAntBuilder@62b07301 antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@3dbfb745 artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@4bbf11cf asDynamicObject: DynamicObject for root project 'HelloWorld' baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@187dbbc2 buildDir: /Users/juklinglee/AndroidStudioProjects/HelloWorld/build buildFile: /Users/juklinglee/AndroidStudioProjects/HelloWorld/build.gradle ......
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
查看編譯環境
juk@JukLings-MacBook-Pro HelloWorld % /Users/juk/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle -q buildEnvironment ------------------------------------------------------------ Root project 'HelloWorld' ------------------------------------------------------------ classpath +--- com.android.tools.build:gradle:7.1.2 | +--- com.android.tools:sdk-common:30.1.2 | | +--- com.android.tools:sdklib:30.1.2 | | | +--- com.android.tools.layoutlib:layoutlib-api:30.1.2 | | | | +--- com.android.tools:common:30.1.2 | | | | | +--- com.android.tools:annotations:30.1.2 | | | | | +--- com.google.guava:guava:30.1-jre | | | | | | +--- com.google.guava:failureaccess:1.0.1 | | |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
查看某個task的詳細使用信息,如查看build 任務:
juklinglee@JukLings-MacBook-Pro HelloWorld % /Users/juklinglee/.gradle/wrapper/dists/gradle-7.2-bin/2dnblmf4td7x66yl1d74lt32g/gradle-7.2/bin/gradle help --task build > Configure project :app C/C++: Could not execute cmake at ...... > Task :help Detailed task information for build Paths :app:build :houseware:build Type Task (org.gradle.api.Task) Description Assembles and tests this project. Group build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
現在,通過查詢我們知道build任務就是用來構建項目的。
最后,以上內容只是gradle的冰山一角,但是看它的源碼,你將能很好的理解它是怎么工作的。
Gradle Github地址
Android Gradle
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。