當使用Android套用框架時,Android系統會通過一些C/C++庫來支持我們使用的各個組件,使其能更好地為我們服務。
*Bionic系統 C 庫:C語言標準庫,系統最底層的庫,C庫通過Linux系統來調用。
*多媒體庫(MediaFramework):Android系統多媒體庫,基於PacketVideo OpenCORE,該庫支持多種常見格式的音頻、視頻的回放和錄製,以及圖片,比如MPEG4、MP3、AAC、AMR、JPG、PNG等。
*SGL:2D圖形引擎庫。
*SSL:位於TCP/IP協定與各種套用層協定之間,為數據通信提供支持。
*OpenGL ES 1.0:3D效果的支持。
*SQLite:關係資料庫。
*Webkit:Web瀏覽器引擎。
*FreeType:點陣圖(bitmap)及矢量(vector)。
每個Java程式都運行在Dalvik虛擬機之上。與PC一樣,每個Android應用程式都有自己的進程,Dalvik虛擬機只執行.dex的執行檔。當Java程式通過編譯,最後還需要通過SDK中的dx工具轉化成.dex格式才能正常在虛擬機上執行。
Google於2007年底正式發布了AndroidSDK,作為Android系統的重要特性,Dalvik虛擬機也第一次進入了人們的視野。它對記憶體的高效使用,以及在低速CPU上表現出的高性能,確實令人刮目相看。Android系統可以簡單地完成進程隔離和執行緒管理。每一個Android套用在底層都會對應一個獨立的Dalvik虛擬機實例,其代碼在虛擬機的解釋下得以執行。
很多人認為Dalvik虛擬機是一個Java虛擬機,因為Android的程式語言恰恰就是Java語言。但是這種說法並不準確,因為Dalvik虛擬機並不是按照Java虛擬機的規範來實現的,兩者並不兼容。它們有兩個明顯的不同:Java虛擬機運行的是Java位元組碼,而Dalvik虛擬機運行的則是其專有的檔案格式為dex(Dalvik Executable)的檔案。在Java SE程式中的Java類會被編譯成一個或者多個位元組碼檔案(.class)然後打包到jar檔案,而後Java虛擬機會從相應的class檔案和jar檔案中獲取相應的位元組碼;Android套用雖然也是使用Java語言進行編程,但是在編譯成class檔案後,還會通過一個工具(dx)將套用所有的class檔案轉換成一個dex檔案,而後Dalvik虛擬機會從其中讀取指令和數據。
Dalvik虛擬機非常適合在移動終端上使用,相對於在桌面系統和伺服器系統運行的虛擬機而言,它不需要很快的CPU計算速度和大量的記憶體空間。根據Google的測算,64MB的記憶體已經能夠讓系統正常運轉了。其中24MB被用於底層系統的初始化和啟動,另外20MB被用於啟動高層服務。當然,隨著系統服務的增多和套用功能的擴展,其所消耗的記憶體也勢必越來越大。歸納起來,Dalvik虛擬機有如下幾個主要特徵:
(1)專有的dex檔案格式。dex是Dalvik虛擬機專用的檔案格式,而為什麼棄用已有的位元組碼檔案(.class檔案)而採用新的格式呢?原因如下:
*每個套用中會定義很多類,編譯完成後即會有很多相應的class檔案,class檔案中會有大量冗餘信息,而dex檔案格式會把所有的class檔案內容整合到一個檔案中。這樣,除了減少整體的檔案尺寸和I/O操作外,也提高了類的查找速度。
*增加了對新的操作碼的支持。
*檔案結構儘量簡潔,使用等長的指令,藉以提高解析速度。
*儘量擴大隻讀結構的大小,藉以提高跨進程的數據共享。
(2)dex的最佳化。dex檔案的結構是緊湊的,但是如果還想運行時的性能有進一步提高,就需要對dex檔案進一步最佳化。最佳化主要針對以下幾個方面:
*調整所有欄位的位元組序(LITTLE_ENDIAN)和對齊結構中的每一個域。
*驗證DEX檔案中的所有類。
*對一些特定的類和方法裡的操作碼進行最佳化。
(3)基於暫存器。相對於基於堆疊實現的虛擬機,基於暫存器實現的虛擬機雖然在硬體、通用性上要差一些,但是它在代碼的執行效率上卻更勝一籌。
(4)一個套用,一個虛擬機實例,一個進程。每一個Android套用都運行在一個Dalvik虛擬機實例中,而每一個虛擬機實例都是一個獨立的進程空間。虛擬機的執行緒機制、記憶體分配和管理、Mutex等的實現都依賴底層作業系統。所有Android套用的執行緒都對應一個Linux執行緒,虛擬機因而可以更多地依賴作業系統的執行緒調度和管理機制。不同的套用在不同的進程空間裡運行,對不同來源的套用都使用不同的Linux用戶來運行,可以最大程度地保護套用的安全和獨立運行。