search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

Android 系統架構和應用組件那些事

繼上一期淺談了Android的前世今生,這一期一起來大致回顧一下Android 系統架構和應用組件。

一、Android 系統架構

Android系統的底層建立在Linux系統之上,該平台由操作系統、中間件、用戶界面和應用軟體4層組成,它採用一種被稱為軟體疊層(Software Stack)的方式進行構建。這種軟體疊層結構使得層與層之間相互分離,明確各層的分工。這種分工保證了層與層之間的低耦合,當下層的層內或層下發生改變時,上層應用程序無須任何改變。

Android的系統架構和其他操作系統一樣,採用了分層的架構。從架構圖看,Android分為四個層,從高層到低層分別是應用程序層(Applications)、應用程序框架層(Application Framework )、系統運行庫層(Libraries和Android Runtime)和Linux內核層(Linux Kernel),如下圖所示:

01 應用程序層

應用程序層是一個核心應用程序的集合,所有安裝在手機上的應用程序都屬於這一層。該層不僅包括系統內置的應用也包括用戶自己安裝的應用,例如email 客戶端,SMS 短消息程序,日曆,地圖,瀏覽器,聯繫人管理程序,QQ,微信,淘寶,美團等。

該層所有的應用程序都是使用Java 語言編寫的,這也是本次主要總結整理的內容。

02 應用程序框架層

開發人員也可以完全訪問核心應用程序所使用的API框架。該應用程序的架構設計簡化了組件的重用,任何一個應用程序都可以發布它的功能塊並且任何其它的應用程序都可以使用其所發布的功能塊(不過得遵循框架的安全性)。同樣,該應用程序重用機制也使用戶可以方便的替換程序組件。

隱藏在每個應用後面的是一系列的服務和系統,其中包括:

1)豐富而又可擴展的視圖(Views),可以用來構建應用程序, 它包括列表(List)、網格(Grid)、文本框(Text)、按鈕(Button), 甚至可嵌入web瀏覽器。

2)內容提供者(Content Providers),使得應用程序可以訪問另一個應用程序的數據(如聯繫人資料庫),或者共享它們自己的數據。

3)資源管理器(Resource Manager),提供非代碼資源的訪問,如本地字元串、圖形、和布局文件(Layout files )。

4)通知管理器 (Notification Manager),使得應用程序可以在狀態欄中顯示自定義的提示信息。

5)活動管理器(Activity Manager),用來管理應用程序生命周期並提供常用的導航回退功能。

應用程序框架除了可作為應用程序開發的基礎之外,也是軟體復用的重要手段,任何一個應用程序都可發布它的功能模塊——只要發布時遵守了框架的約定,那麼其他應用程序就可使用這個功能模塊。

03 系統運行庫層

系統運行庫層包含了系統庫及Android運行時。

系統庫

Android包含一套被不同組件所使用的C/C++庫的集合。一般來說,Android應用開發者不能直接調用這套C/C++庫集,但可以通過它上面的應用程序框架來調用這些庫。

下面列出一些核心庫:

1)系統C庫:一個從BSD系統派生出來的標準C系統庫(libc),並且專門為嵌入式 Linux設備調整過。

2)媒體庫:基於PacketVideo的OpenCORE,這套媒體庫支持播放和錄製許多流行的音 頻和視頻格式,以及查看靜態圖片。主要包括MPEG4、H.264、MP3、AAC、AMR、JPG、PNG等多媒體格式。

3)Surface Manager:管理對顯示子系統的訪問,並可以對多個應用程序的2D和3D圖 層提供無縫整合。

4)LibWebCore:一個全新的Web瀏覽器引擎,該引擎為Android瀏覽器提供支持,也為WebView提供支持,WebView完全可以嵌入開發者自己的應用程序中。

5)SQLite:供所有應用程序使用的功能強大的輕量級關係資料庫。

6)OpenGL ES:該庫可以使用硬體3D加速(如果可用)或者使用高度優化的3D軟加速。

7)FreeType:點陣圖(Bitmap)和矢量(Vector)字體顯示。

8)SGL:底層的2D 圖形引擎。

Android運行時(Android Runtime)

Android運行時由兩部分組成:Android核心庫集和ART。其中核心庫集提供了Java語言核心庫所能使用的絕大部分功能,而虛擬機則負責運行Android應用程序。

Android 5.0以前的Android運行時由Dalvik虛擬機和Android核心庫集組成,但由於Dalvik 虛擬機採用了一種被稱為JIT (Just-in-time)的解釋器進行動態編譯並執行,因此導致Android App運行時比較慢;而ART模式則是在用戶安裝App時進行預編譯(Ahead-of-time,簡稱AOT)的,將原本在程序運行時的編譯動作提前到應用安裝時,這樣使得程序在運行時可以減少動態 編譯的開銷,從而提升Android App的運行效率。

反過來,由於ART需要在安裝App時進行AOT處理,因此ART需要佔用更多的存儲空 間,應用安裝和系統啟動時間會延長不少。

除此之外,ART還支持ARM、x86和MIPS架構,並且能完全兼容64位系統,Android必然會帶來更好的用戶體驗。

04 Linux內核層

Android系統主要基於Linux2.6內核開發,Linux內核層為Android設備的各種硬體提供了底層的驅動,如顯示驅動、音頻驅動、照相機驅動、藍牙驅動、電源管理驅動等。

Linux 內核也同時作為硬體和軟體棧之間的抽象層。

二、Dalvik虛擬機和ART模式

01 Dalvik虛擬機

通過JavaSE部分的學習,我們知道JavaSE 程序使用的虛擬機叫Java Virtual Machine,簡稱JVM。而Android 應用雖然使用Java 語言開發,但是使用的虛擬就是Dalvik Virtual Machine,簡稱DVM。

Dalvik是Google公司自己設計的用於Android平台的虛擬機,它可以簡單地完成進程隔離和線程管理,並且可以提高內存的使用效率。每一個Android應用程序在底層都會對應一個獨立的Dalvik虛擬機實例,其代碼在虛擬機的解析下得以執行。Dalvik 經過優化,允許在有限的內存中同時運行多個虛擬機的實例,並且每一個Dalvik 應用作為一個獨立的Linux 進程執行。

很多人都認為Dalvik虛擬機是一個Java虛擬機,因為Android開發的編程語言恰恰是 Java語目,但是這種說法並不准確。Dalvlk虛擬機並不是按照Java虛擬機的規範來實現的,兩者不兼容,而且也有很多不同之處。下面通過一個圖來進行對比說明,如下圖所示。

從上圖可以看出,Java虛擬機和Dalvik虛擬機主要有兩大區別:一是它們編譯后的文件不同;二是它們基於的架構不同。具體如下:

編譯后的文件不同

Java虛擬機運行的是.class位元組碼文件,而Dalvik虛擬機運行的則是其專有的.dex文件。 在Java程序中Java類會被翻譯成一個或者多個位元組碼文件(.class )然後打包到.jar文件,之後Java虛擬機會從相應的.class文件和.jar文件中獲取相應的位元組碼。Android程序雖然也是使用Java語言進行編程,但是在翻譯成.class文件后,還會通過工具將所有的.class文件轉換成一個.dex文件,然後Dalvik虛擬機從其中讀取指令和數據,最後的.odex是為了在運行過程中進一步提高性能而對.dex文件進行的進一步優化,能加快軟體的載入速度和開啟速度。

基於的架構不同

Java虛擬機是基於棧的架構,大家知道,棧是一個連續的內存空間,取出和存人的速度比較慢;而Dalvik基於寄存器的架構,寄存器是CPU上的一塊緩存,寄存器的存取速度要比從內存中存取的速度快很多,這樣就可以根據硬體最大限度地優化設備,更適合移動設備的使用。

需要說明的是,Android系統下的Dalvik虛擬機默認給每一個應用程序最多分配16 MB 內存,如果Android載入的資源超過這個值,就會報出OutOfMemoryError異常,因此一定要注意這個問題。

02 ART模式

ART模式英文全稱為Android Runtime,是谷歌Android 4.4系統新增的一種用運行模式。與傳統的Dalvik模式不同,ART模式可以實現更為流暢的安卓系統體驗,只有在Android 4.4以上系統中採用此模式。

在4.4 系統之前,Android 系統在Linux 的底層下構築Dalvik 一層的虛擬機,通過其可以更好適應多樣的硬體架構,開發者只需要按一套規則進行應用便可,無需因為不同的硬體架構而處理與底層的驅動關係,從而大大提高開發的效率,但因為應用均是運行在Dalvik 虛擬機中,因此應用程序每次運行的時候,一部分代碼都需要重新進行編譯,這過程需要消耗一定的時間和降低應用的執行效率,最明顯的便是拖延了應用的啟動時間和降低了運行速度。

ART 模式最大的作用就是提升了Android 系統流暢度,相比Dalvik 模式中出現的耗電快、佔用內存大、即使是旗艦機用久了也會卡頓嚴重等現象,ART 模式中這種問題得到了很好的解決,通過在安裝應用程序時,自動對程序進行代碼預讀取編譯,讓程序直接編譯成機器語言,免去了Dalvik 模式要時時轉換代碼,實現高效率、省電、佔用更低的系統內存、手機運行流暢。

三、Android應用組件

Android四大組件分別是:

活動(Activity): 用於表現功能。

服務(Service): 後台運行服務,不提供界面呈現。

廣播接收器(BroadcastReceiver):用於接收廣播。

內容提供者(Content Provider): 支持在多個應用中存儲和讀取數據,相當於資料庫。

01 Activity

Android中,Activity是所有程序的根本,所有程序的流程都運行在Activity之中,Activity可以算是開發者遇到的最頻繁,也是Android 當中最基本的模塊之一。在Android的程序當中,Activity 一般代表手機屏幕的一屏。如果把手機比作一個瀏覽器,那麼Activity就相當於一個網頁。在Activity當中可以添加一些Button、Check box等控制項。可以看到Activity概念和網頁的概念相當類似。

一般一個Android 應用是由多個Activity 組成的。這多個Activity之間可以進行相互跳轉,例如,按下一個Button按鈕后,可能會跳轉到其他的Activity。和網頁跳轉稍微有些不一樣的是,Activity 之間的跳轉有可能返回值,例如,從Activity A 跳轉到Activity B,那麼當Activity B運行結束的時候,有可能會給Activity A一個返回值。這樣做在很多時候是相當方便的。

當打開一個新的屏幕時,之前一個屏幕會被置為暫停狀態,並且壓入歷史堆棧中。用戶可以通過回退操作返回到以前打開過的屏幕。可以選擇性的移除一些沒有必要保留的屏幕,因為Android會把每個應用的開始到當前的每個屏幕保存在堆棧中。

02 Service

Service 是android 系統中的一種組件,它跟Activity 的級別差不多,但是他不能自己運行,只能後台運行,並且可以和其他組件進行交互。Service 是沒有界面的長生命周期的代碼。Service是一種程序,它可以運行很長時間,但是它卻沒有用戶界面。

這麼說有點枯燥,來看個例子。打開一個音樂播放器的程序,這個時候若想上網了,那麼,打開Android瀏覽器,這個時候雖然已經進入了瀏覽器這個程序,但是,歌曲播放並沒有停止,而是在後台繼續一首接著一首的播放。其實這個播放就是由播放音樂的Service進行控制。當然這個播放音樂的Service也可以停止,例如,當播放列表裡邊的歌曲都結束,或者用戶按下了停止音樂播放的快捷鍵等。

Service 可以在和多場合的應用中使用,比如播放多媒體的時候用戶啟動了其他Activity這個時候程序要在後台繼續播放,比如檢測SD 卡上文件的變化,再或者在後台記錄地理信息位置的改變等等,總之服務嘛,總是藏在後頭的。

03 BroadcastReceiver

在Android 中,Broadcast是一種廣泛運用的在應用程序之間傳輸信息的機制。而BroadcastReceiver 是對發送出來的Broadcast進行過濾接受並響應的一類組件。可以使用BroadcastReceiver 來讓應用對一個外部的事件做出響應。

這是非常有意思的,例如,當電話呼入這個外部事件到來的時候,可以利用BroadcastReceiver 進行處理。例如,當下載一個程序成功完成的時候,仍然可以利用BroadcastReceiver 進行處理。BroadcastReceiver不能生成UI,也就是說對於用戶來說不是透明的,用戶是看不到的。BroadcastReceiver通過NotificationManager 來通知用戶這些事情發生了。BroadcastReceiver 既可以在AndroidManifest.xml 中註冊,也可以在運行時的代碼中使用Context.registerReceiver進行註冊。只要是註冊了,當事件來臨的時候,即使程序沒有啟動,系統也在需要的時候啟動程序。各種應用還可以通過使用Context.sendBroadcast 將它們自己的Intent Broadcasts廣播給其他應用程序。

04 Content Provider

Content Provider 是Android提供的第三方應用數據的訪問方案。

在Android中,對數據的保護是很嚴密的,除了放在SD卡中的數據,一個應用所持有的資料庫、文件等內容,都是不允許其他直接訪問的。Android當然不會真的把每個應用都做成一座孤島,它為所有應用都準備了一扇窗,這就是Content Provider。應用想對外提供的數據,可以通過派生Content Provider類, 封裝成一枚Content Provider,每個Content Provider都用一個uri作為獨立的標識,形如:content://com.xxxxx。所有東西看著像REST的樣子,但實際上,它比REST 更為靈活。和REST類似,uri也可以有兩種類型,一種是帶id的,另一種是列表的,但實現者不需要按照這個模式來做,給id的uri也可以返回列表類型的數據,只要調用者明白,就無妨,不用苛求所謂的REST。

寫在最後

今天就先到這裡,下一期將初步總結分享Android環境搭建,如果有問題歡迎留言一起探討,共同成長!

此文章版權為微信公眾號分享達人秀所有,若轉載請備註出處,特此聲明



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦