Android 系統概要 ——《第一行代碼 Android》

《第一行代碼 Android》作為Android入門書籍,由郭霖大神編寫的,這本書相對比其他入門書籍比較基礎并且深度也不錯。本文主要是針對第一章概況讀書簡記,便于日后溫故,總結。

Android 系統起源

首先,作為一名Android開發人員來說,對于Android系統怎么而來的,想必大家或多或少聽說一些。Android作為現如今擁有用戶群體的手機系統,起初是由Andy Rubin(“Android之父”)同其他三位創始人成立了“Android公司“,為了數碼相機開發出來的一套基于Linux系統,這便是Android的雛形。

隨后,Android轉而開發手機操作系統,并于2005年被谷歌收購,Rubin和其他創始人留在谷歌,開始了真正意義上的智能手機操作系統開發。在這個時候,Android系統的方向已經確定,比如基于Linux、開源、免費供手機廠商使用等等,谷歌則可將其服務深度集成到系統中獲得利潤。

2008年,谷歌發布了第一版Android系統”Android 1.0“,接著在2009年發布了1.1版本,隨后在1.5版本開始出現以甜點命名版本,具體版本如下:

Android Beta,發布于2007年11月5日,同時的軟件開發套件(SDK),發布于2007年11月12日。 11月5日被認為是Android的"生日"。

Android版本名稱Code name Android版本 版本發布時間 對應API
(no code name) 1.0 2008年9月23日 API level 1
(no code name) 1.1 2009年2月2日 API level 2
Cupcake 1.5 2009年4月17日 API level 3,NDK 1
Donut 1.6 2009年9月15日 API level 4,NDK 2
Eclair 2.0.1 2009年12月3日 API level 6
Eclair 2.1 2010年1月12日 API level 7,NDK3
Froyo 2.2.x 2010年1月12日 API level 8,NDK 4
Gingerbread 2.3 – 2.3.2 2011年1月1日 API level 9,NDK5
Gingerbread 2.3.3 – 2.3.7 2011年9月2日 API level 10
Honeycomb 3.0 2011年2月24日 API level 11
Honeycomb 3.1 2011年5月10日 API level 12,NDK 6
Honeycomb 3.2.x 2011年7月15日 API level 13
Ice Cream Sandwich 4.0.1 – 4.0.2 2011年10月19日 API level 14,NDK 7
Ice Cream Sandwich 4.0.3 – 4.0.4 2012年2月6日 API level 15,NDK 8
Jelly Bean 4.1 2012年6月28日 API level 16
Jelly Bean 4.1.1 2012年6月28日 API level 16
Jelly Bean 4.2-4.2.2 2012年11月 API level 17
Jelly Bean 4.3 2013年7月 API level 18
KitKat 4.4 2013年7月24日 API level 19
Kitkat Watch 4.4W 2014年6月 API level 20
Lollipop(Android L) 5.0/5.1 2014年6月25日 API level 21/API level 22
Marshmallow(Android M) 6.0 2015年5月28日 API level 23
Nougat(Android N) 7.0 2016年5月18日 API level 24
Nougat(Android N) 7.1 2016年12月 API level 25
Oreo(Android O) 8.0 2017年8月22日 API level 26
Oreo(Android O) 8.1 2017年12月5日 API level 27
Pie (Android P)不是鳳梨酥(PineappleCake) 9.0 2018年8月7日 API level 28

Android的版本,有個API Level,對應著某個Android發布版本的名稱。

Android系統架構

上面我們大概了解了Android的起源以及對應的版本,并且也大概知道Android是基于Linux系統開發出來的移動終端系統,那接下來我們來了解下Android系統的內部架構,Android大致可以分為四層架構:Linux內核層系統運行庫層應用框架層應用層

  • Linux內核層:
    Android系統基于Linux內核,這一層為Android設備的各種硬件提供了底層的去驅動,如顯卡驅動、音頻驅動、相機驅動、藍牙驅動、WIFI驅動、電源管理等。

  • 系統運行庫層:
    這層通過一些C/C++庫為Android系統提供了主要的特性支持,例如SQLite庫提供了數據庫的支持,OpenGL|ES庫提供了3D繪圖的支持,Webkit庫提供了瀏覽器內核的支持等等。
    同樣在這一層,還有谷歌為我們提供的Android運行時庫,它主要提供了一些核心庫,能夠允許開發者使用Java語言來編寫Android應用。另外,Android運行時庫中還包含了Dalvik虛擬機(5.0系統之后改為ART運行環境,這兩種環境在本質上有很大的區別,導致Android在運行性能方面更加優越,具體區別在后期會獨篇說明,這里不過多闡述),它使得每個Android應用都能運行在獨立的進程中,并且擁有自己的虛擬機實例。相對比于Java虛擬機,Android虛擬機是專門為移動設備定制的,它針對手機內存、CPU性能有限等情況做了優化處理。

  • 應用框架層
    這層主要提供了構建應用程序時可能用到的各種API,Android自帶的一些核心應用就是使用這些API完成的。

  • 應用層
    所有安裝在手機上的應用程序都屬于這一層的,比如系統內置的聯系人、短信等程序,或者從應用商城上下載下來的應用以及自己開發的程序都屬于這層。

Android系統架構可以參考如下圖:

Android系統架構

Android開發環境搭建

針對于開發環境搭建,都是每個開發者老生常談的必要走的一步,這里就不多累贅,只是貼出各個環境下載鏈接,便于日后查詢配置使用。

  • JDK
  • Android Studio(可能部分小伙伴需要墻,也可以訪問百度云盤資源)
  • Android SDK一般這塊不需要單獨下載,谷歌已經將其集成到Android Studio中了,如果小伙伴有需要下載,也可以在 Android Studio上瀏覽到Command line tools only選擇即可。

關于小伙伴在使用Android Studio過程中可能會遇到一些構建常見問題,可以詳情了解下我的另外一篇文字《Android Studio 構建常見出錯問題匯總》,以及《Android Studioc常用快捷鍵匯總》,不定時更新哦!

Android Studio目錄結構分析

Android在早期開發還是使用Eclipse比較多,但自從2013年官方推出Android Studio(以下簡稱AS)之后,Android開發更多的傾向于使用AS開發,而且在推出AS之后,官方也相應停止了Eclipse開發Android對應的ADT更新,所以現在大部分都是采用AS開發。在這里有必要扯一下AS目錄結構,畢竟兩個IDE的編譯機制是有所不同的,在Eclipse采用的Ant方式構建編譯項目,而在AS中采用的是Gradle。

Eclipse在這我就不過多闡述了,我們要跟緊時代腳步,所以這里主要講下AS中項目對應目錄結構的功能與作用,新建一個項目,可得到如下所示:

Project模式的項目結構
  1. .gradle和.idea
    這兩個目錄下放置的都是AS自動生成的一些文件,所以這塊我們不用關心,在拷貝項目備份或者版本管理時候,可以忽略這兩個目錄。

  2. app
    項目中的代碼、資源等內容幾乎都在這個目錄下,日常編寫代碼大部分也都在這個目錄下進行的,所以這個目錄的文件結構后面會單獨解析具體底層目錄。

  3. build
    在AS高版本中這個目錄已經不存在,低版本中存在這個目錄,也是AS編譯時自動生成的文件,不用關心,在拷貝項目備份或者文件管理時候,同樣是可以忽略的目錄。

  4. gradle
    在這個目錄下包含了gradle wrapper的配置文件,使用gradle wrapper的方式無需提前將gradle下載好,而是會自動根據本地的緩存情況決定是否需要聯網下載gradle。

  5. .gitignore
    這個文件用來將指定的目錄或文件排除在版本控制(Git)之外的。

  6. build.gradle
    這個文件是全局的gradle的構建腳本,通常這個文件中的內容是不需要修改的。后面會具有分析gradle構建腳本的內容。

  7. gradle.properties
    這個文件是全局的gradle配置文件,在這里配置的屬性會影響到項目中所有的gradle編譯腳本。

  8. gradlew 和 gradlew.bat
    這個兩個文件是用來在命令行界面(Terminal)中執行gradle命令的,其中gradlew是在Linux或Mac系統中使用的,gradlew.bat是在windows系統中使用的。

  9. HelloWorld.iml
    iml文件是所有IntelliJ IDEA項目都會自動生成的一個文件(AS是基于IntelliJ IDEA開發的),用于標識這是由IntelliJ IDEA項目,不需要修改此文件,可以在備份或者版本控制時候忽略。

  10. local.properties
    文件是用于指定本機中的Android SDK路徑,以及NDK路徑,通常不需要修改,除非本地環境發生改變時候。

  11. setting.gradle
    這個文件同于指定項目中所有引入的模塊,由于此處只有app一個模塊,因此該文件這里只引入的app這一個模塊。通常情況都是自動完成的,只有手動導入模塊時候,可能需要手動去修改。

整個項目的外層結構基本到這有一個大致的了解,接下來說下app目錄,也就是我們代碼經常需要修改調整的目錄下的結構,如下所示:

app目錄下的結構
  1. build
    這個目錄和外層的build目錄相似,主要也是包含了編譯自動生成的文件,同樣也無需關心,可以備份或者版本控制可以忽略。

  2. libs
    項目中使用第三方jar包,需要把對應的jar包放在這個目錄下,放在這個目錄下的jar包會被自動添加到構建路徑里去。

  3. androidTest
    此處用來編寫AndroidTest測試用例的,可以對項目進行一些自動化測試。

  4. java
    此處用于編寫應用的主要邏輯Java代碼。

  5. res
    這個目錄主要存放應用的UI布局字符串等資源,這個目錄相對比較復雜,在子目錄layout下主要存放應用的布局文件,而圖片根據不同的分辨率存放在以drawble-xxx目錄下,當然有些類似selector選擇器或者Shape自定義形狀等等這些還是放在drawble中,子目錄values下主要存放字符串、樣式以及主題等。
    在這個目錄所有子目錄下有一個子目錄mipmap-xxx需要特別說明以下,mipmap是在Android Jelly Beans 4.3中提出來的,主要是為了讓程序能夠更好的兼容各種設備,在處理Launcher Icon圖片渲染方面更加強大。

  6. AndroidManifest.xml
    這個文件是整個應用的配置文件,在程序中定義的所有四大組件都必須在這個文件里注冊,在這個文件配置需要的相應權限配置聲明。

  7. test
    此處用來編寫Unit Test測試用例的,是對項目進行自動化測試的另外一種方式。

  8. .gitignore
    這個文件用于app模塊內的指定的目錄或文件的排除在版本控制(Git)之外,作用與外層的.gitignore,但一般都在外層的.gitignore全局設置了。

  9. app.iml
    IntelliJ IDEA項目自動生成的文件,不需要去修改與關心,備份或版本控制時候可以忽略。

  10. build.gradle
    app模塊的gradle構建腳本,這個文件會指定很多項目構建相關的配置。

  11. proguard-rules.pro
    這個文件用于指定項目代碼的混淆規則,當我們的代碼編寫打包成apk時候,如果不希望別人破解,通常會將代碼進行混淆,從而讓破解者難以閱讀,考慮安全點,一般還會對apk進行加固。

因為Android Studio是采用Gradle來構建項目的,所以這里對Gradle的配置文件進一步講解。Gradle是一個非常先進的項目構建工具,它使用了一種基于Groovy的領域特定語言(DSL)來聲明項目設置,摒棄了傳統基于XML(如Ant和Maven)的各種煩瑣配置。

這里先說說項目外層中build.gradle文件的配置,如下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

這些代碼都是自動生成的,大部分情況下不需要我們去修改,但也得大概知道其意思。

首先兩處repositories的閉包中聲明了google()、jcenter()配置,它們代表不同的代碼托管倉庫,很多的Android開源項目都會或多或少引用了谷歌提供開源項目,所以需要聲明google(),而很多的Android開源項目都會選擇將代碼托管到jcenter上,聲明了jcenter之后,我們就可以很方便的使用任何jcenter上的開源項目了。

接下來,dependencies閉包中使用了classpath聲明了一個Gradle插件。為什么要聲明這個插件呢?原來Gradle并不只是專門為構建Android項目而開發的,java、C++等很多項目都可以使用Gradle來構建。因此想要使用它來構建Android項目,則需要聲明com.android.tools.build:gradle:3.0.1'這個插件,其中,最后冒號后面部分是插件的版本號,例如我現在這個項目中使用的插件版本是3.0.1.

分析完外層的build.gradle文件后,還需要分析模塊里面的build.gradle文件,如下:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"
    defaultConfig {
        applicationId "com.anand.activitylifecycletest"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.0.0-beta1'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:0.5'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
}

這個文件相對復雜一些,首先第一行應用了一個插件,一般有兩種值可選:com.android.application表示這是一個應用程序模塊,com.android.library表示這是一個庫模塊。應用程序模塊與庫模塊最大的區別在于一個是可以直接運行的,一個只能作為代碼庫依附于別的應用程序模塊來運行。

緊接著是android這個閉包,可以配置項目構建的各種屬性。其中,compileSdkVersion用于指定項目的編譯版本,這里指定26表示使用Android 8.0系統的SDK編譯,buildToolsVersion用于指定項目構建工具的版本,這里使用了26.0.2版本。

接著是嵌套下的defaultConfig閉包,defaultConfig閉包中可以對項目進行更多的配置。其中,applicationId用于指定項目的包名,一般修改應用包名,可對這個配置進行修改。minSdkVersion用于指定項目最低兼容的Android系統版本,這里指定成15表示最低兼容到Android 4.0系統。targetSdkVersion指定的值表示在該目標版本上已經做過了充分測試,系統將會為其應用程序啟用一些最新的功能和特性。舉例說Android 6.0系統中引入了運行時權限這個功能,如果我們將targetSdkVersion指定成23或者更高,那么系統就會認為你的程序已經做好充分測試,將為你啟用運行時權限,而如果將targetSdkVersion指定成22,那么說明程序最高只在Android 5.1系統上做過充分的測試,Android 6.0系統中引入的新功能自然就不會啟用。剩下的versionCode用于指定項目的版本號,versionName用于指定項目版本名,這個兩個在安裝應用文件以及版本升級方面比較重要。testInstrumentationRunner為谷歌推薦的
AndroidJUnitRunner單元測試(這塊是Android Studio2.2以后推出的,這塊我也是第一次接觸,后期有學習再深入探索)

接著分析下buildTypes閉包。buildTypes閉包用于指定生成安裝文件的相關配置。通常情況下會有兩個子閉包,一個debug,一個releasedebug閉包用于指定生成測試版安裝文件的配置,release閉包用于指定生成正式版安裝文件的配置。另外,debug閉包是可以忽略不寫的,因此默認情況下我們看到代碼中只有一個release閉包。接下來,我們來看下debugrelease閉包中具體內容吧,minifyEnable用于指定是否對項目代碼進行混淆操作,true表示混淆,false 表示不混淆。proguardFiles用于指定混淆時使用的規則文件,這里指定了兩個文件,第一個proguard-android.txt是在Android SDK下\tools\proguard目錄下,這里是所有項目的通用的混淆規則;第二個proguard-rules.pro是在當前項目的根目錄下的,里面可以編寫當前項目特有的混淆規則。需要注意的是,通過AS直接運行項目生成都是測試版本安裝文件,除非手動切換BuildVariants設置。

分析完android閉包,緊接著分析最后一個dependencies閉包。這個閉包主要作用在于指定當前項目所有的依賴關系。通常AS項目一共有3種依賴關系:本地依賴庫依賴遠程依賴本地依賴可以對本地的Jar包、aar包或者目錄添加依賴關系,庫依賴可以對項目中的庫模塊添加依賴關系,遠程依賴則可以對jcenter庫上的開源項目添加依賴關系。
觀察dependencies閉包中的配置,第一行implementation fileTree就是一個本地依賴聲明,表示將 libs目錄下所有.jar后綴的文件都添加到項目的構建路徑當中。而第二行的implementation則是遠程依賴聲明,com.android.support:appcompat-v7:26.0.0-beta1就是一個標準的遠程依賴庫格式,其中com.android.support是域名部分,用于和其他公司的庫做區分;appcompat-v7是組名稱,用于和同一個公司中不同的庫做區分;26.0.0-beta1是版本號,用于和同一個庫不同的版本做區分。加上這句聲明后,Gradle在構建項目時會首先檢查一下本地是否已經存在這個庫的緩存,如果沒有的話則會自動去互聯網下載,然后再添加到項目的構建路徑當中。至于庫依賴這里沒有使用到,它的基本格式是implementation project后面加上要依賴的庫名稱,例如有一個庫模塊的名稱叫helper,那么添加這個庫依賴的聲明只需要加入implementation project(':helper')即可。后面一些是聲明主要是為了聲明測試用例庫的,后期會單獨詳細說明下,具體參考Android 項目中的幾種單元測試用例

Android 的日志工具使用

Android中使用的日志工具是Log(android.util.Log),這個類提供了5個方法來打印日志。

  • Log.v()。用于打印那些最為瑣碎的、意義最小的日志信息。對應級別verbose,是Android日志里面級別最低的一種。
  • Log.d()。用于打印一些調式信息,這些信息對你調試程序和分析問題有幫助的。對應級別debug,比verbose高一級。
  • Log.i()。用于打印一些比較重要的數據。這些數據應該是開發者非常想要看到的,可以幫助開發者分析用戶行為數據。對應級別info,比debug高一級。
  • Log.w()。用于打印一些警告信息,提示程序在這個地方可能會有潛在的風險,最好去修復一下這些出現警告的地方。對應級別warn,比info高一級。
  • Log.e()。用于打印程序中的錯誤信息,比如程序進入到了catch語句當中。當有錯誤信息打印出來的時候,一般都代表你的程序出現嚴重問題了,必須盡快修復。對應級別error,比warn高一級。

關于為什么使用Log而不使用System.out疑問?
System.out.print對應Java初學者開說應該很熟悉,在Eclipse中syso就可以快速打印出信息來,那么為什么Android不使用這個方法,而采用多級別的Log呢,主要的原因是打印不可控、打印時間無法確定、不能添加過濾器、日志沒級別區分。對于程序比較復雜的情況下,日志比較多的情況下,快速定位問題無法很快定位到。

關于Log日志一些快捷鍵操作可以參考《Android Studioc常用快捷鍵匯總》中的Tab組合快捷鍵。

除了快捷鍵, AS還為Log日志提供了locat方便我們過濾查詢日志,讓我們可以快速定位到對應的日志上。AS目前為開發者提供了3個過濾器,Show only selected application表示只顯示當前選中程序中的日志,Firebase是谷歌提供的一個分析工具,No Filters相當于沒有過濾器,會把所有的日志都顯示出來。當然除了一首AS提供的三種過濾器,也可以自定義自己的過濾器,選擇Edit Filter Configuration會彈出一個過濾器配置界面,可以自行配置自定義過濾器,在Log Tag中對需要過濾的tag進行配置。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容