編輯:關於Android編程
使用gradle構建android應用時,你總是需要這樣一個文件:build.gradle。你應該已經看過這個文件了,如果沒有看過的話,你現在就可以看一下,它沒有多少內容。它的簡潔性得益於它提供了很多對設置和屬性的默認值。gradle是基於groovy語言的,但就使用它構建普通的工程的話,是可以不去學groovy的,如果想深入的做一下自定義的構建插件,可以考慮學一下groovy,因為它是基於java的,所以你有java基礎的話,學習不會很難。
這篇博客旨讓任何一個人能看懂android studio的gradle scripts,主要會從gradle的簡單語法,gradle scripts的腳本結構,每一個腳本(build.gradle,settings.gradle)的作用,腳本中每一項的意義等方面說明gradle scripts.
是的,工程,任務和行為。一個項目至少要有一個工程,一個工程至少要有一個任務,一個任務由一些action組成。如果project比較抽象的話,可以這麼理解,一個build.gradle對應一個project,而action就好像java中的方法,他就是一段代碼的集合。在工程構建的過程中,gradle會根據build.gradle中的配置信息生成相應的project和task。
1.1.1初始化階段。根據build.gradle創建一個project實例。每一個project對應一個build.gradle腳本。也就是說這個過程會解析buile.gradle腳本,並使用它創建若干個project實例。
1.1.2配置階段。根據腳本配置委托對象。
1.1.3執行階段。執行tasks。
task標示一個邏輯上的執行單元,可以這樣聲明一個task:
task haha { println "haha" }然後使用gradle haha命令,就會打印出haha。這裡,haha這個任務被執行了,所以說task就是個執行單元。你還可以使用如下方法來定義task:
task hello << { println "hello world" }這和前者是有區別的,“<<”意思是給hello這個task添加一些action,其實就是調用了task的doLast方法,所以,它和以下代碼時等價的:
task hello { doLast{ println "hello world" } }在android studio的頂層build.gradle中有這樣一個task:
task clean(type: Delete) { delete rootProject.buildDir }可以看到這個task有一個類型type,task有很多種類型的,以下列出來一些:
這裡用到了delete類型,task的類型可以這樣理解吧:task中文就是任務,任務有很多種類,Delete就是說這是個刪除文件的任務。
這裡就不更深入的探討task了,這些類容已經可以使我們可以理解android studio中遇到的內容了。
DSL(Domain Specific Language),中文意思是特定領域的語言。gradle DSL就是gradle領域的語言。為了更好理解gradle,學習gradle DSL是有必要的。gradle的腳本雖然非常簡短,但它有它的語法,如果不搞懂DSL,即便你知道了怎麼修改腳本得到你想要的結果,你也不會理解為什麼要這樣修改。
第一. gradle script是配置腳本,當腳本被執行的時候,它配置一個特定的對象。比如說,在android studio工程中,build.gradle被執行的時候,它會配置一個Project對象,settings.gradle被執行時,它配置一個Settings對象。Project,Settings這種對象就叫做委托對象,下圖展示了不同腳本對應的不同的委托對象:
第二.每一個Gradle script實現了一個Script接口,這意味著Script接口中定義的方法和屬性都可以在腳本中使用。
一個腳本由零個或多個statements和 script blocks組成。以下是對他們的說明,為了避免翻譯錯誤,這裡把原文貼出來。
A build script is made up of zero or more statements and script blocks. Statements can include method calls, property assignments, and local variable definitions. A script block is a method call which takes a closure as a parameter. The closure is treated as aconfiguration closurewhich configures some delegate object as it executes. The top level script blocks are listed below.
大概意思statments可以包括方法調用,屬性分配,本地變量定義;script bolck則是一個方法,它的參數可以是一個閉包。這個閉包是一個配置閉包,因為當它被執行的時候,它用來配置委托對象。以android studio的build.gradle為例:
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.konka.gradletest" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' }
apply plugin: 'com.android.application'
以上就是一條statements,其中apply 是一個方法,後面是它的參數。
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' }以上是一個script block,它其實是一個方法(method),它的參數是一個閉包,閉包會被執行,用來配置它對應的委托對象。
gradle中有以下頂層script block:
這裡再以allprojects{ }為例,說一下script block是怎麼工作的:
allprojects { repositories { jcenter() } }
allprojects{ }一般是頂層build.gradle中的一個script block,它就是一個方法,這個方法接受一個閉包作為參數。gradle工具會先創建一個Project對象,它是一個委托對象(delegate object),它創建以後,build.gradle被執行,執行的過程中,allproject{ }方法被調用,這個方法的參數是一個閉包,然後閉包會被執行,用來配置Project對象。
理解了Project,task和action的概念以後,就可以就理解gradle的配置文件了。在android studio的工程中一般會有三個配置文件,它們各有各的功能。這三個文件的位置應該是這樣的:
如果一個新的工程只包含一個android app,那麼settings.gradle應該是這樣的:
include ':app'如果你的工程裡只有一個 app,那麼settings.gradle文件可以不要。include ':app'中的app指明你要構建的模塊名,android studio默認的模塊名師app,你可以把app目錄的名字改掉,比如改成hello,那麼這個時候你就必須把settings.gradle中的app也改成hello。這會是你非常有意義的一次嘗試,因為有了這次嘗試,以後你就可以按你所願修改這個文件了。比如就像這樣修改:
那麼這個時候你肯定已經想試試一次性構建多個app了吧?你以前如果做過,那麼你很厲害,你就不用看了,如果你沒有試過,那麼就和我一起試試吧:
第一步:在你的工程上右鍵,選擇新建mudole。
第二步:你成功了!
是的就這麼簡單,現在看看工程的樣子:
是的,這個時候,settings.gradle中多了一項,他就是我們新加的module的名字,它其實就是工程頂層目錄下的一個目錄的名字。這個名字你可以隨便改,module你也可以隨便加。
注意:settings.gradle實在初始化階段被讀入的,讀入以後會生成一個Settings對象,然後會調用這個對象的一些方法。你沒有必要了解這個對象,你知道它的存在對你理解項目構建的過程有所幫助。
就是頂層的build.gradle腳本。這個文件中配置內容將會應用到所有modules中(上一步我們已經創建了兩個module了,一個hello,一個gradletest2)。所以,每個module中都有的共同的屬性,都會在頂層的build.gradle中配置,它默認有以下內容:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
這個腳本是由buildscript {},allprojects{} 兩個script block組成,buildsctipt是一個頂層的script block,正如2.2中所說的那樣,是一個方法,參數是一個閉包,這個閉包裡面又有一些script block,它們的本質都是一樣的。最終這些閉包會被執行,用來配置對應的委托對象。比如,repositories這個方法的閉包調用了jcenter方法,這個方法會配置gradle的遠程倉庫,配置好了以後,在工程構建過程中,如果缺少依賴,就會在遠程倉庫中查找。頂層build.gradle中的配置會應用到所有的工程中,頂層build.gradle的委托對象是root Project,子工程目錄下的build.gradle對應它自己的Project,總之,一個build.gradle對應一個Project。
到這裡,應該能看懂一個gradle script了,至於每個script block的意義,但從字面意思上就能猜出一些來,比如allprojects {}就是為所有的project配置閉包中的內容,這裡就是配置遠程倉庫,倉庫有很多種,想使用其他倉庫就可以在這裡修改。buildsctipt{}為所有project配置構建用的倉庫的工具,它裡面的dependecbies{}就是配置構建工具的信息,從中可以看到構建工具是gradle,版本是2.0.0;所以,修改gradle的版本就可以在這裡改。
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.konka.gradletest" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' }3.3.1第一行是一個statement,調用了apply方法,這個方法的定義如下:
void apply(Map它的作用是檢查gradle有沒有所聲明的這個插件,有就什麼都不做,沒有的話就會使插件可用。options);
具體的每一個script block,它們都是方法,都可以在android studio 中按住ctrl+鼠標左鍵,點進去看它的聲明,每個方法都有注釋來解釋它的作用。
3.3.1 android block
android 是這個腳本中最大的塊,它包含了andoird特有的插件,這些插件可以使用是因為之前調用了
apply plugin: 'com.android.application',
此外,這裡設置了編譯android用的參數,構建類型等。
3.3.2 dependencies block
這裡設置了編譯當前的app的依賴。如果當前app依賴外部的包,可以把這個包放到libs目錄下面,然後右鍵,選擇add as library,
然後就會在這裡生成一條compile ' ... '的記錄。
3.3.3還有其他的一些配置,比如:
//這個是解決lint報錯的代碼 lintOptions { abortOnError false } //簽名設置 signingConfigs { myConfigs { storeFile file("簽名文件地址") keyAlias "..." keyPassword "..." storePassword "..." } } //混淆設置 buildTypes { release { signingConfig signingConfigs.myConfigs runProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } //渠道打包(不同包名) productFlavors { aaa{ applicationId = '包名' } bbb{ applicationId='包名' } } } //so文件的導入 task copyNativeLibs(type: Copy) { from fileTree(dir: 'libs', include: 'armeabi/*.so') into 'build/lib' }
總結:其實我覺得理解gradle的關鍵是理解script bolck與方法的對應關系,build.gradle等腳本與Project等對象的對應關系,以及理解Project和task的概念,這樣就基本對gradle有了很好地理解。然後再去研究每一個scripts block或者說是方法的作用,了解他們也很簡單,可以直接ctrl+鼠標左鍵點進去看這些方法的定義,看看他們的注釋就可以初步理解他們的功能了。
GlideGlide是一個高效、開源、 Android設備上的媒體管理框架,它遵循BSD、MIT以及Apache 2.0協議發布。Glide具有獲取、解碼和展示視頻劇照、
首先,附上程序運行後的效果,如下圖所示: 一.部署一個web項目到tomcat服務器上:1.這個小程序是結合網絡來播放一首音樂的,首先,把我們搞好的
通知的使用,無疑是Android系統的亮點之一;就連IOS在5.0開始也引入了類似通知的技巧。可見它的實用性。今天這個小案例,就學習一下通知的基本使用,API是使用最新的
本文實例講述了Android編程實現號碼歸屬地查詢的方法。分享給大家供大家參考,具體如下:我們通過發送XML訪問 WebService就可以實現號碼的歸屬地查詢,我們可以