讀古今文學網 > Android程序設計:第2版 > Android應用時運行的環境 >

Android應用時運行的環境

Android獨特的應用組件架構在某種程度上是Android多處理並發的產物。為了使該環境能夠適應多個供應商的多種應用,信任每個供應商只需要很少的工作,Android執行Dalvik VM的多個實例,每個任務執行一個實例。在P83「組件生命週期」一節以及後續的章節中,我們將探討組件生命週期如何促進Android提高應用堆內的垃圾收集工作,以及如何促進多個堆之間的內存回收策略。

由於這種簡單而又可靠的多處理方式,Android必須高效地把內存劃分成多個堆。每個堆相對較小,這樣內存可以支持多個應用同時運行。在每個堆中,由於有了組件生命週期而使得不使用的組件,尤其是當前不活躍的用戶界面組件,在堆的空間緊張時能夠執行垃圾回收,而在需要時能夠重新獲取。因此,由這種方式又引入了以數據庫為中心的數據模型,其中大部分數據都是內在持久的,關於這一點本書後面將會更加詳細地討論,尤其是第10章。

Dalvik虛擬機

Android的多路處理利用了虛擬機的多進程和多實例,需要虛擬機的每個實例都能有效利用空間。這是通過組件生命週期來完成的,它使得對像某種程度上能夠通過虛擬機本身執行垃圾回收和重新創建。Android通過Dalvik虛擬機運行特地為Android開發的字節碼系統,該字節碼系統名為dex。dex字節碼的空間效率幾乎是Java字節碼的兩倍,對於每個進程,從根本上看,在內存消耗上僅為Java類的一半。Android系統還使用寫時複製(copy-on-write)的內存管理方式來實現同一個Dalvik可執行文件的多個實例之間的堆內存的共享。

Zygote:派生新的進程

當每個新的進程啟動虛擬機的一個新的實例時,如果每次都加載所有必要的基類,則效率會很低。由於Android把每個應用放在獨立的進程中,它會利用底層Linux操作系統的fork操作,通過模板進程生成新的進程,該進程在啟動新的虛擬機實例時能夠達到最優狀態。該模板進程的名字就是Zygote。Zygote模板進程是Dalvik虛擬機的一個實例,它包含一組預加載類及Zygote進程的其他狀態,這些進程通過fork操作生成Zygote的副本。

沙盒:進程和用戶

Android的安全在很大程度上依賴於Linux操作系統層的安全機制,尤其對於進程和用戶級別的邊界限制。由於Android面向的是個人設備,即個人持有和使用的設備,Android巧妙地利用了Linux內在的多用戶支持特性:為每個應用供應商創建一個單獨的用戶。這意味著每個應用以不同的用戶權限運行(除了那些來自同一個供應商的)。在默認情況下,一個應用所擁有的文件,其他應用是無法訪問的。

這就類似於在Windows系統上,你以自己的用戶名運行Word程序,而以同事的用戶名運行Web瀏覽器。無論要切換查看Word還是Web瀏覽器,都需要首先退出,然後切換用戶才能查看,而無法同時查看。Android允許一個登錄的手機用戶查看以不同的Linux級別用戶運行的多個應用。

這種方式帶來的直接影響是由於每個應用在自己的「獨立運行空間(silo)」中執行,因而安全性得到了提高。

桌面操作系統通常不會如此全面地考慮應用的沙盒特徵——一旦安裝了某個應用,用戶的所有數據都會信任該應用。Android設計師們設想的是來自眾多供應商的很多小的應用,這些供應商並非都是完全可信的。因此,一個應用無法直接訪問其他應用的數據。

關於Android安全性的完整描述可以在Android文檔中獲取:http://developer.android.com/guide/topics/security/security.html。

Android庫

Android引入了一些新的軟件包,這些軟件包和傳統的Java(J2SE)軟件包一起組成了Android運行時環境API。我們一起來看看這些API組合包含了哪些內容。

Android和dalvik

這些軟件包括了Android運行時環境中Android專有的所有部分。本書的大部分主題都是圍繞著這些庫展開的,具體包括:Android GUI和文本處理庫(android.graphics、android.view、android.widget和android.text),以及應用框架庫,名為android.app、android.content和android.database。此外,還包含一些其他核心的、面向移動的框架,如android.telephony和android.webkit。熟練的Android程序員至少應該對前面幾個包非常熟悉。可以按照Android軟件包的樹形透視圖來遍歷Android文檔,可以從下面這個地址中Android開發者文檔的最上方開始查看:http://developer.android.com/reference/packages.html。

java

Java這個軟件包包含核心Java運行時庫的實現。java.lang包包含類Object的實現,類Object是所有Java對象的基類,java.util包包含Java集合框架:Array、Lists、Map、Set和Iterator及它們的實現。Java集合庫(Java Collections Library)提供了Java語言的一組精心設計的數據結構——有了它們你不需要編寫自己的鏈表數據結構。

如第2章所述,java.util包包含了源於兩個不同譜系的集合,一些是源於Java 1.1,另一些是源於更新版本的Java的集合重新設計理念。Java 1.1中的集合(如Vector和Hashtable)是完全同步的,並且其接口不是很一致。新版本的Java中的集合(如HashMap和ArrayList)不是同步的,一致性更好,因此是編程人員的首選。

為了保持和Java語言的兼容性,Android庫也包含一些遺留類的實現,但應盡量避免使用這些類。舉個例子,Collections框架包含類Dictionary,該類已經顯式廢棄。Enumeration(枚舉)接口已經被Iterator(迭代器)取代,TimerTask已經被Concurrency框架中的ScheduledThreadPoolExecutor取代。Android參考文檔很清楚地標識出了這些遺留類型。

java還包含一些其他經常用到的對象(如Currency、Date、TimeZone和UUID)的基本類型,以及I/O、網絡、並發和安全的基礎框架。

在Android版本的java包層次結構中,不包含awt包和rmi包。awt包被Android的GUI庫所取代。遠程消息機制(RMI)並沒有與其一一對應的替換者,但是內部的ServiceProviders使用了Parcelables,如P116「序列化」一節所述,提供了類似的功能。

javax

javax包和java包非常相似。它包含Java語言的一部分官方實現。javax庫的行為是完全明確的,但是它不是Java語言的完整實現的一部分。因為Android運行時環境並不包含一些必需的部分,和Android包存在一定的區別,但還是盡可能看起來和Java包一樣。javax包和Android包的樹形結構都包含了組成Java語言的庫的實現。

javax包中最重要的實現是XML框架。XML框架包含SAX和DOM解析器、XPath的實現,以及XSLT的實現。

此外,javax包還包含了一些重要的安全擴展和OpenGL API。一個經驗豐富的Java開發人員會注意到javax包中缺少了Android運行時環境實現的一些重要部分,尤其是那些和UI以及多媒體相關的部分。Javax不包含javax.swing、javax.sound以及其他類似的部分。這些部分都由Android特定的包所取代。

org.apache.http

org.apache.http軟件包樹包含標準的Apache HTTP客戶端、服務器和HttpCore的實現。該軟件包提供了使用HTTP進行通信的所有必須功能的實現,包括表示消息、頭、鏈接、請求和響應的所有類的實現。

Apache HttpCore項目的更多信息可以在下面這個頁面中查看:http://hc.apache.org/httpcomponents-core/index.html。

org.w3c.dom、org.xml.sax、org.xmlpull和org.json

這些包是一些常用的數據格式的公共的API定義:XML(http://www.w3,org/standards/xml/)、XML Pull(http://www.xmlpull.org/index.shtml)和JSON(http://www.json.org/)。