Android Studio工程目錄結(jié)構(gòu)分析
我們這里以一個簡單的HelloWorld工程來分析:
Android Studio工程目錄
1、.gradle和.idea
? ? 這兩個目錄下放置的都是Android Studio自動生成的一些文件,我們無須關(guān)心,也不要去手動編輯。
2、app
? ? 項目中的代碼、資源等內(nèi)容幾乎都是放置在這個目錄下的,我們后面的開發(fā)工作也基本都是在這個目錄下進(jìn)行的,待會兒還會對這個目錄單獨展開進(jìn)行講解。
3、build
? ? 這個目錄你也不需要過多關(guān)心,它主要包含了一些在編譯時自動生成的文件。
4、gradle
? ? 這個目錄下包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前將gradle下載好,而是會自動根據(jù)本地的緩存情況決定是否需要聯(lián)網(wǎng)下載gradle。Android Studio默認(rèn)沒有啟動gradle wrapper的方式,如果需要打開,可以點擊Android Studio導(dǎo)航欄 --> File --> Settings --> Build,Execution,Deployment --> Gradle,進(jìn)行配置更改。
5、.gitignore
? ? 這個文件是用來將指定的目錄或文件排除在版本控制之外的。
6、build.gradle
? ? 這是項目全局的gradle構(gòu)建腳本,通常這個文件中的內(nèi)容是不需要修改的。下面會詳細(xì)分析gradle構(gòu)建腳本中的具體內(nèi)容。
7、gradle.properties
? ? 這個文件是全局的gradle配置文件,在這里配置的屬性將會影響到項目中所有的gradle編譯腳本。
8、gradlew和gradlew.bat
? ? 這兩個文件是用來在命令行界面中執(zhí)行g(shù)radle命令的,其中g(shù)radlew是在Linux或Mac系統(tǒng)中使用的,gradlew.bat是在Windows系統(tǒng)中使用的。
9、HelloWorld.iml
? ? iml文件是所有IntelliJ IDEA項目都會自動生成的一個文件(Android Studio是基于IntelliJ IDEA開發(fā)的),用于標(biāo)識這是一個IntelliJ IDEA項目,我們不需要修改這個文件中的任何內(nèi)容。
10、local.properties
? ? 這個文件用于指定本機(jī)中的Android SDK路徑,通常內(nèi)容都是自動生成的,我們并不需要修改。除非你本機(jī)中的Android SDK位置發(fā)生了變化,那么就將這個文件中的路徑改成新的位置即可。
11、settings.gradle
? ? 這個文件用于指定項目中所有引入的模塊。由于HelloWorld項目中就只有一個app模塊,因此該文件中也就只引入了app這一個模塊。通常情況下模塊的引入都是自動完成的,需要我們手動去修改這個文件的場景可能比較少。
app目錄結(jié)構(gòu)
? ? 現(xiàn)在整個項目的外層目錄結(jié)構(gòu)已經(jīng)介紹完了。你會發(fā)現(xiàn),除了app目錄之外,大多數(shù)的文件和目錄都是自動生成的,我們并不需要進(jìn)行修改。想必你已經(jīng)猜到了,app目錄下的內(nèi)容才是我們以后的工作重點,展開之后結(jié)構(gòu)如下:
? ? 那么下面我們就來對app目錄下的內(nèi)容進(jìn)行更為詳細(xì)的分析。
1、build
? ? 這個目錄和外層的build目錄類似,主要也是包含了一些在編譯時自動生成的文件,不過它里面的內(nèi)容會更多更雜,我們不需要過多關(guān)系。
2、libs
? ? 如果你的項目中使用到了第三方j(luò)ar包,就需要把這些jar包都放在libs目錄下,放在這個目錄下的jar包都會被自動添加到構(gòu)建路徑里去。
3、AndroidTest
? ? 此處是用來編寫Android Test測試用例的,可以對項目進(jìn)行一些自動化測試。
4、java
? ? 毫無疑問,java目錄是放置我們所有java代碼的地方,展開該目錄,你將看到我們剛才創(chuàng)建的HelloWorldActivity文件就在里面。
5、res
? ? 這個目錄下的內(nèi)容就有點多了。簡單點說,就是你在項目中使用到的所有圖片,布局,字符串等資源都要存放在這個目錄下。當(dāng)然這個目錄下還有很多子目錄,圖片放在drawable目錄下,布局放在layout目錄下,字符串放在values目錄下,所以你不用擔(dān)心會把整個res目錄弄得亂糟糟的。
6、AndroidManifest.xml
? ? 這是你整個Android項目的配置文件,你在程序中定義的所以四大組件都需要在這個文件里注冊,另外還可以在這個文件中給應(yīng)用程序添加權(quán)限聲明。
7、test
? ? 此處是用來編寫Unit Test測試用例的,是對項目進(jìn)行自動化測試的另一種方式。
8、.gitignore
? ? 這個文件用于將app模塊內(nèi)的指定的目錄或文件排除在版本控制之外,作用和外層的.gitignore文件類似。
9、app.iml
? ??IntelliJ IDEA項目自動生成的文件,我們不需要關(guān)心或修改這個文件中的內(nèi)容。
10、build.gradle
? ? 這是app模塊的gradle構(gòu)建腳本,這個文件中會指定很多項目構(gòu)建相關(guān)的配置。
11、proguard-rules.pro
? ? 這個文件用于指定項目代碼的混淆規(guī)則,當(dāng)代碼開發(fā)完成后打成安裝包文件,如果不希望代碼被別人破解,通常會將代碼混淆,從而讓破解者難以閱讀。
項目中的資源
? ??? ??如果你展開res目錄看一下,其實里面的東西還是挺多的,很容易讓人看得眼花繚亂,如下圖:
? ? 看到這么多的文件夾也不用害怕,其實歸納一下,res目錄就變得非常簡單了。
所以以drawable開頭的文件夾都是用來放圖片的,
所有以mipmap開頭的文件夾都是用來放應(yīng)用圖標(biāo)的,
所有以values開頭的文件夾都是用來放字符串、樣式、顏色等配置的,
layout文件夾是用來放布局文件的。
最外層目錄下的build.gradle
HelloWorld項目中有兩個build.gradle文件,一個是在最外層目錄下的,一個是在app目錄下的。這兩個文件對構(gòu)建AndroidStudio項目都起到了至關(guān)重要的作用,下面我們就來對這兩個文件中的內(nèi)容進(jìn)行詳細(xì)的分析。
先來看一下最外層目錄下的build.gradle文件,代碼如下所示:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Gradle中可以使用“//”或“/**/”來添加注釋,與Java類似。
// 根目錄下的build.gradle用于添加子工程或模塊共用的配置項。
// "buildscript"的類型為script block,而且是最上層的script block,用于配置Gradle的Project實例。其API文檔為https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:buildscript(groovy.lang.Closure)
// 其余的根script block有"allprojects", "dependencies", "configurations"等,更多的可見https://docs.gradle.org/current/dsl/的“Build script structure”一節(jié)。
// Script Block是一種method的調(diào)用,傳入的參數(shù)為configuration closure。執(zhí)行后會對Project的屬性進(jìn)行配置。
// 此處的"buildscript"用于配置Project的build script的classpath。
buildscript?{
// 如果需要的話,從https://jcenter.bintray.com/下載code reposities。
repositories?{
jcenter()
}
// 定義classpath,gradle會從“repositories”中下載對應(yīng)版本的Gradle。如果使用gradle wrapper的話,感覺這個配置會被忽略。Wrapper會自己去下載所使用的gradle版本。
dependencies?{
classpath?'com.android.tools.build:gradle:2.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
// 該配置會被應(yīng)用到所有的子工程。
allprojects?{
repositories?{
jcenter()
}
}
// 運(yùn)行g(shù)radle clean時,執(zhí)行此處定義的task。
// 該任務(wù)繼承自Delete,刪除根目錄中的build目錄。
// 相當(dāng)于執(zhí)行Delete.delete(rootProject.buildDir)。
// gradle使用groovy語言,調(diào)用method時可以不用加()。
task clean(type:?Delete)?{
delete?rootProject.buildDir
}
? ? 這些代碼都是自動生成的,雖然語法結(jié)構(gòu)看上去可能有點難以理解,但是如果我們忽略語法結(jié)構(gòu),只看最關(guān)鍵的部分,其實還是很好懂的。
首先,兩處repositories的閉包中都聲明了jcenter()進(jìn)行配置,那么這個jcenter是什么意思呢?其實它是一個代碼托管倉庫,很多Android開源項目都會選擇將代碼托管到j(luò)center上,聲明了這行配置之后,我們就可以在項目中輕松引用任何jcenter上的開源項目了。
? ? 接下來,dependencies閉包中使用classpath聲明了一個Gradle插件。為什么要聲明這個插件呢?因為Gradle并不是專門為構(gòu)建Android項目而開發(fā)的,java,c++等很多項目都可以使用Gradle來構(gòu)建。因此如果我們要想使用它來構(gòu)建Android項目,則需要聲明com.android.tools.build:gradle:2.2.2這個插件。其中,最后面的部分是插件的版本號。
? ? 這樣我們就將最外層目錄下的build.gradle文件分析完了,通常情況下你并不需要修改這個文件中的內(nèi)容,除非你想添加一些全局的項目構(gòu)建配置。
app目錄下的的build.gradle
? ? 下面我們再來看一下app目錄下的build.gradle文件,代碼如下所示:
apply plugin:?'com.android.application'
android?{
compileSdkVersion?23
buildToolsVersion?"23.0.3"
defaultConfig?{
applicationId?"com.example.helloworld"
minSdkVersion?15
targetSdkVersion?23
versionCode?1
versionName?"1.0"
testInstrumentationRunner?"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes?{
release?{
minifyEnabled?false
proguardFiles getDefaultProguardFile('proguard-android.txt'),?'proguard-rules.pro'
}
}
}
dependencies?{
compile fileTree(include:?['*.jar'],?dir:?'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',?{
exclude group:?'com.android.support',?module:?'support-annotations'
})
compile?'com.android.support:appcompat-v7:23.4.0'
testCompile?'junit:junit:4.12'
}
這個文件中的內(nèi)容就要相對復(fù)雜一些,下面我們一行行地進(jìn)行分析。首先第一行應(yīng)用了一個插件,一般有兩種值可選:com.android.application表示這是一個應(yīng)用程序模塊,com.android.library表示這是一個庫模塊。應(yīng)用程序模塊和庫模塊的最大區(qū)別在于,一個是可以直接運(yùn)行的,一個只能作為代碼庫依附于別的應(yīng)用程序模塊來運(yùn)行。
接下來是一個大的android閉包,在這個閉包中我們可以配置項目構(gòu)建的各種屬性。其中,compileSdkVersion用于指定項目的編譯版本,這里指定成23表示使用Android 6.0系統(tǒng)的SDK編譯。buildToolsVersion 用于指定項目構(gòu)建工具的版本,目前使用的版本是23.0.3。
然后我們看到,這里在android閉包中又嵌套了一個defaultConfig閉包,defaultConfig閉包中可以對項目的更多細(xì)節(jié)進(jìn)行配置。其中,applicationId 用于指定項目的包名,前面我們在創(chuàng)建項目的時候其實已經(jīng)指定過包名了,如果你想在后面對其進(jìn)行修改,那么就是在這里修改的。minSdkVersion 用于指定項目最低兼容的Android系統(tǒng)版本,這里指定成15表示最低兼容到Android 4.0系統(tǒng)。targetSdkVersion 指定的值表示你在該目標(biāo)版本上已經(jīng)做過了充分的測試,系統(tǒng)將會為你的應(yīng)用程序啟用一些最新的功能和特性。比如說Android 6.0系統(tǒng)中引入了運(yùn)行時權(quán)限這個功能。而如果你將targetSdkVersion 指定成22,那么就說明你的程序最高只在Android 5.1系統(tǒng)上做過充分的測試,Android 6.0系統(tǒng)中引入的新功能自然就不會啟用了。剩下的幾個屬性都比較簡單,versionCode用于指定項目的版本號,versionName用于指定項目的版本名,這兩個屬性在生成安裝文件的時候非常重要。
分析完了defaultConfig閉包,接下來我們看一下buildTypes閉包。buildTypes閉包中用于指定生成安裝文件的相關(guān)配置,通常只會有兩個子閉包,一個是debug,一個是release。debug閉包用于指定生成測試版安裝文件的配置,release閉包用于指定生成正式版安裝文件的配置。另外,debug閉包是可以忽略不寫的,因此我們看到上面的代碼中就只有一個release閉包。下面來看一下release閉包中的具體內(nèi)容吧,minifyEnabled用于指定是否對項目的代碼進(jìn)行混淆,true 表示混淆,false 表示不混淆。proguardFiles 用于指定混淆時使用的規(guī)則文件,這里指定了兩個文件,第一個proguard-android.,txt 是在Android SDK目錄下的,里面是所有項目通用的混淆規(guī)則,第二個 proguard-rules.pro 是在當(dāng)前項目的根目錄下的,里面可以編寫當(dāng)前項目特有的混淆規(guī)則。需要注意的是,通過AndroidStudio直接運(yùn)行項目生成的都是測試版安裝文件。
這個整個android閉包中的內(nèi)容就都分析完了,接下來還剩下一個dependencies閉包。這個閉包的功能非常強(qiáng)大,它可以指定當(dāng)前項目所有的依賴關(guān)系。通常AndroidStudio項目一共有3種依賴方式:本地依賴、庫依賴和遠(yuǎn)程依賴。本地依賴可以對本地的jar包或目錄添加依賴關(guān)系,庫依賴可以對項目中的庫模塊添加依賴關(guān)系,遠(yuǎn)程依賴則可以對jcenter庫上的開源項目添加依賴關(guān)系。觀察一下dependencies閉包中的配置,第一行的compile fileTree就是一個本地依賴聲明,它表示將libs目錄下所有.jar后綴的文件都添加到項目的構(gòu)建路徑當(dāng)中。而第三行compile 則是遠(yuǎn)程依賴聲明,com.android.support:appcompat-v7:23.4.0就是一個標(biāo)準(zhǔn)的遠(yuǎn)程依賴庫格式,其中com.android.support是域名部分,用于和其他公司的庫做區(qū)分;appcompat-v7是組名稱,用于和同一個公司中不同的庫做區(qū)分;23.4.0是版本號,用于和同一個庫不同的版本做區(qū)分。加上這句聲明后,Gradle在構(gòu)建項目時會首先檢查一個本地是否已經(jīng)有這個庫的緩存,如果沒有的話則會去自動聯(lián)網(wǎng)下載,然后再添加到項目的構(gòu)建路徑當(dāng)中。至于庫依賴聲明這里沒有用到,它的基本格式是compile project后面加上要依賴的庫名稱,比如說有一個庫模塊的名字叫helper,那么添加這個庫的依賴關(guān)系只需要加入compile project(':helper')這句聲明即可。
深入了解三個文件
接下來我們就要剖析工程里三個比較重要的文件: MainActivity.java,布局文件:activity_main和Android配置文件:AndroidManifest.xml
1、MainActivity.java:
2、布局文件:activity_main.xml:
3、配置文件AndroidManifest.xml:
AndroidManifest文件中含有如下過濾器的Activity組件為默認(rèn)啟動類當(dāng)程序啟動時系統(tǒng)自動調(diào)用它
1
2
3
4