一: Android系統架構
Android大致可以分爲四層架構:Linux內核層、系統運行庫層、應用框架層和應用層。
Linux內核層:
Android系統是基於Linux內核的,這一層爲Android設備的各種硬件提供了底層的驅動,如顯示驅動、音頻驅動、照相機驅動、藍牙驅動、Wi-Fi驅動、電源管理等。
系統運行庫層:
這一層通過一些C/C++庫來爲Android系統提供了主要的特性支持。如SQLite庫提供了數據庫的支持,0penGL|ES庫提供了 3D繪圖的支持,Webkit庫提供了瀏覽器內核的支持等。同樣在這一層還有Android運行時庫,它主要提供了一些核心庫,能夠允許開發者使用Java 語言來編寫Android應用。另外,Android運行時庫中還包含了 Dalvik虛擬機(5.0系統之後改爲 ART運行環境),它使得每一個Android應用都能運行在獨立的進程當中,並且擁有一個自己的 Dalvik虛擬機實例。相較於Java虛擬機,Dalvik是專門爲移動設備定製的,它針對手機內存、 CPU性能有限等情況做了優化處理。
應用框架層:
這一層主要提供了構建應用程序時可能用到的各種API, Android自帶的一些核心應用就是 使用這些API完成的,開發者也可以通過使用這些AH來構建自己的應用程序。
應用層:
所有安裝在手機上的應用程序都是屬於這一層的,比如系統自帶的聯繫人、短信等程序,或者是你從Google Play上下載的小遊戲,當然還包括你自己開發的程序。
二: Android Studio 目錄結構
把項目結構模式切換爲Project:
.gradle 和.idea
這兩個目錄下放置的都是Android Studio自動生成的一些文件,我們無須關心,也不要去手動編輯。app
項目中的代碼、資源等內容幾乎都是放置在這個目錄下的,我們後面的開發工作也基本都是 在這個目錄下進行的,待會兒還會對這個目錄單獨展開進行講解。build
這個目錄你也不需要過多關心,它主要包含了一些在編譯時自動生成的文件。gradle
這個目錄下包含了 gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前將gradle 下載好,而是會自動根據本地的緩存情況決定是否需要聯網下載gradle。Andmid Studio默認沒有 啓用gradle wrapper的方式,如果需要打開,可以點擊Android Studio導航欄–>File–>Settings–>Build, Execution, Deployment–>Gradle,進行配置更改。.gitignore
這個文件是用來將指定的目錄或文件排除在版本控制之外build.gradle
這是項目全局的gradle構建腳本,通常這個文件中的內容是不需要修改的gradle.properties
這個文件是全局的gradle配置文件,在這裏配置的屬性將會影響到項目中所有的gradle編譯 腳本。gradlew 和 gradlew.bat
這兩個文件是用來在命令行界面中執行gradle命令的,其中gradlew是在Linux或Mac系統 中使用的,gradlew.bat是在Windows系統中使用的。HelloWorld.iml
iml文件是所有IntelliJ IDEA項目都會自動生成的一個文件(Android Studio是基於IntelliJ IDEA開發的),用於標識這是一個IntelliJIDEA項目,我們不需要修改這個文件中的任何內容。local.properties
這個文件用於指定本機中的Android SDK路徑,通常內容都是自動生成的,我們並不需要修改。 除非你本機中的Andmid SDK位置發生了變化,那麼就將這個文件中的路徑改成新的位置即可。settings.gradle
這個文件用於指定項目中所有引入的模塊.通常情況下模塊的引入都是自動完成的,需要我們手 動去修改這個文件的場景可能比較少。
那麼下面我們就來對app目錄下的內容進行更爲詳細的分析。
build
這個目錄和外層的build目錄類似,主要也是包含了一些在編譯時自動生成的文件,不過它 裏面的內容會更多更雜,我們不需要過多關心。libs
如果你的項目中使用到了第三方jar包,就需要把這些jar包都放在libs目錄下,放在這個目 錄下的jar包都會被自動添加到構建路徑裏去。src/androidTest
此處是用來編寫Android Test測試用例的,可以對項目進行一些自動化測試src/main/java
毫無疑問,java目錄是放置我們所有Java代碼的地方,展開該目錄,你將看到我們剛纔創建 的HelloWorldActivity文件就在裏面。src/main/res
這個目錄下的內容就有點多了。簡單點說,就是你在項目中使用到的所有圖片、佈局、字符 串等資源都要存放在這個目錄下。當然這個目錄下還有很多子目錄,圖片放在drawable目錄下,布 局放在layout目錄下,字符串放在values目錄下,所以你不用擔心會把整個res目錄弄得亂糟糟的AndroidManifest.xml
這是你整個Android項目的配置文件,你在程序中定義的所有四大組件都需要在這個文件裏 註冊,另外還可以在這個文件中給應用程序添加權限聲明test
此處是用來編寫Unit Test測試用例的,是對項目進行自動化測試的另一種方式。.gitignore
這個文件用於將app模塊內的指定的目錄或文件排除在版本控制之外,作用和外層 的.gitignore文件類似。app.iml
IntelliJIDEA項目自動生成的文件,我們不需要關心或修改這個文件中的內容build.gradle
這是app模塊的gmdle構建腳本,這個文件中會指定很多項目構建相關的配置,我們稍後將 會詳細分析gradle構建腳本中的具體內容。proguard-rules.pro
這個文件用於指定項目代碼的混淆規則,當代碼開發完成後打成安裝包文件,如果不希望代 碼被別人破解,通常會將代碼進行混淆,從而讓破解者難以閱讀
三:詳解項目中的資源以及使用
- 以drawable開頭的文件夾都是用來放圖片的
- 以values開頭的文件夾都是用來放字符串的
- layout文件夾是用來放佈局文件的
- menu文件夾是用來放菜單文件的
之所以有這麼多drawable開頭的文件夾,其實主要是爲了讓程序能夠兼容更多的設備。在製作程序的時候最好能夠給同一張圖片提供幾個不同分辨率的副本,分別放在這些文件夾下,然後當程序運行的時候會自動根據當前運行設備分辨率的高低選擇加載哪個文件夾下的圖片。當然這只是理想情況,更多的時候美工只會提供給我們一份圖片,這時你就把所有圖片都放在drawable-hdpi文件夾下就好了。
知道了res目錄下每個文件夾的含義,我們再來看一下如何去使用這些資源吧。比如剛剛在strings.xml中找到的Hello world!字符串,我們有兩種方式可以引用它:
1.在代碼中通過R.string.hello_world可以獲得該字符串的引用
2.在XML中通過@string/hello_world可以獲得該字符串的引用
基本的語法就是上面兩種方式,其中string部分是可以替換的,如果是引用的圖片資源就可以替換成drawable,如果是引用的佈局文件就可以替換成layout,以此類推。HelloWorld項目的圖標就是在AndroidManifest.xml中通過android:icon=”@drawable/ic_launcher”來指定的,ic_launcher這張圖片就在drawable文件夾下
四:詳解 build.gradle 文件
Android Studio是採用Gradle來構建項目的, Gradle是一個非常先進的項目 構建工具,它使用了一種基於Groovy的領域特定語言(DSL)來聲明項目設置,摒棄了傳統基 於XML (如Ant和Maven)的各種煩瑣配置。
先來看一下最外層目錄下的build.gradle文件,代碼如下所示:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle;2.2.0'
}
}
allprojects {
repositories {
jcenter()
}
}
兩處repositories的閉包中都聲明瞭 jcenter()這行配置,那麼這個jcenter是什麼意思呢?其實它是一個代碼託管倉庫,很多Android開源項目都會選擇將代碼託管到jcenter 上,聲明瞭這行配置之後,我們就可以在項目中輕鬆引用任何jcenter上的開源項目了
dependencies閉包中使用classpath聲明瞭一個Gradle插件。爲什麼要聲明這 個插件呢?因爲Gradle並不是專門爲構建Android項目而開發的,Java、C++等很多種項目都可 以使用Gradle來構建。因此如果我們要想使用它來構建Android項目,貝懦要聲明com.android. tools.build:gradle:2.2.0這個插件。其中,最後面的部分是插件的版本號
下面我們再來看一下app目錄下的build.gradle文件,代碼如下所示;
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationld "com.example.helloworld"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile com.android.support:appcompat-v7:24.2.11
testCompile 1junit:junit:4.12'
}
首先第一行應用了一個插件,一般有兩種值可選:com.android.application表示這是一個應用程序模塊, com.android.library表示這是一個庫模塊。應用程序模塊和庫模塊的最大區別在於,一個是 可以直接運行的,一個只能作爲代碼庫依附於別的應用程序模塊來運行。
接下來是一個大的android閉包,在這個閉包中我們可以配置項目構建的各種屬性。其中compileSdkVersion用於指定項目的編譯版本,這裏指定成24表示使用Android7.0系統的SDK 編譯buildToolsVersion用於指定項目構建工具的版本,這裏表示構建工具版本就是24.0.2
然後我們看到,這裏在android閉包中又嵌套了一個defaultConfig閉包,defaultConfig閉包 中可以對項目的更多細節進行配置。其中,applicationld用於指定項目的包名,前面我們在創建項目的時候其實已經指定過包名了,如果你想在後面對其進行修改,那麼就是在這裏修改的。 minSdkVersion用於指定項目最低兼容的Android系統版本,這裏指定成15表示最低兼容到 Android4.0系統。targetSdkVersion指定的值表示你在該目標版本上已經做過了充分的測試, 系統將會爲你的應用程序啓用一些最新的功能和特性。比如說Android 6.0系統中引入了運行時 權限這個功能,如果你將targetSdkVersion指定成23或者更高,那麼系統就會爲你的程序啓 用運行時權限功能,而如果你將targetSdkVersion指定成22,那麼就說明你的程序最高只在 Android5.1系統上做過充分的測試,Android6.0系統中引入的新功能自然就不會啓用了。剩下的 兩個屬性都比較簡單,versionCode用於指定項目的版本號,versionName用於指定項目的版本名
接下來我們看一下buildTypes閉包。buildTypes閉包中用於指 定生成安裝文件的相關配置,通常只會有兩個子閉包,一個是debug,一個是release。debug閉包用於指定生成測試版安裝文件的配置,release閉包用於指定生成正式版安裝文件的配置。另外, debug閉包是可以忽略不寫的,因此我們看到上面的代碼中就只有一個release閉包。下面來看一 下release閉包中的具體內容吧,minifyEnabled用於指定是否對項目的代碼進行混清,true表示混淆,false表示不混淆。proguardFiles用於指定混清時使用的規則文件,這裏指定了兩 個文件,第一個proguard-android.txt是在Android SDK目錄下的,裏面是所有項目通用的 混淆規則,第二個proguard-rules.pro是在當前項目的根目錄下的,裏面可以編寫當前項目 特有的混淆規則。需要注意的是,通過Android Studio直接運行項目生成的都是測試版安裝文件
接下來還剩一個dependencies閉包。這個閉包的功能非常強大,它可以指定當前項目所有的依賴關係。通常AndroidStudio項目一共有3種依 賴方式:本地依賴、庫依賴和遠程依賴。本地依賴可以對本地的Jar包或目錄添加依賴關係,庫依賴可以對項目中的庫模塊添加依賴關係,遠程依賴則可以對jcenter庫上的開源項目添加依賴關係。 觀察一下dependencies閉包中的配置,第一行的compile fileTree就是一個本地依賴聲明,它表示將libs目錄下所有jar後綴的文件都添加到項目的構建路徑當中。而第二行的compile則是 遠程依賴聲明,com.android.support:appcompat-v7:23.4.0就是一個標準的遠程依賴庫格式, 其中com .android .support是域名部分,用於和其他公司的庫做區分;appcompat-v7是組名稱, 用於和同一個公司中不同的庫做區分;23.4.0是版本號,用於和同一個庫不同的版本做區分。加 上這句聲明後,Gradle在構建項目時會首先檢查一下本地是否已經有這個庫的緩存,如果沒有的話 則會去自動聯網下載,然後再添加到項目的構建路徑當中。至於庫依賴聲明這裏沒有用到,它的基本格式是compile project後面加上要依賴的庫名稱,比如說有一個庫模塊的名字叫helper, 那麼添加這個庫的依賴關係只需要加入compile project(‘:helper’) 這句聲明即可。另外剩下的一句testCompile是用於聲明測試用例庫的,這個我們暫時用不到,先忽略它就可以了。
細節點:
1:所有的四大組件都需要在清單文件中註冊,以下代碼表示把該HelloWorldActivity作爲app啓動頁
<activity
android:name="com.test.helloworld.HelloWorldActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2:AppCompatActivity是一種向下兼容 的Activity,可以將Activity在各個系統版本中增加的特性和功能最低兼容到Android 2.1系統