解讀Android虛擬機工作原理
下面講述下Android虛擬機的組成部分和一些構造原理,在介紹Android虛擬機之前,先要了解下什么是Android操作系統,所謂的Android:是基于Linux內核的軟件平臺和操作系統,早期由Google開發,后由開放手機聯盟Open Handset Alliance)開發。
Linux系統中進程間通信的方式有:socket, named pipe,message queque, signal,share memory。Java系統中的進程間通信方式有socket, named pipe等。android應用程序理所當然可以應用JAVA的IPC機制實現進程間的通信,
取而代之的是Binder通信。Google為什么要采用這種方式呢,這取決于Binder通信方式的高效率。 Binder通信是通過linux的binder driver來實現的。Binder通信操作類似線程遷移(thread migration),兩個進程間IPC看起來就象是一個進程進入另一個進程執行代碼然后帶著執行的結果返回。
Binder的用戶空間為每一個進程維護著一個可用的線程池,線程池用于處理到來的IPC以及執行進程本地消息,Binder通信是同步而不是異步。Android中的Binder通信是基于Service與Client的,所有需要IBinder通信的進程都必須創建一個IBinder接口。
系統中有一個進程管理所有的system service,Android虛擬機不允許用戶添加非授權的System service,當然現在源碼開發了,我們可以修改一些代碼來實現添加底層system Service的目的。
對用戶程序來說,我們也要創建server,或者Service用于進程間通信,這里有一ActivityManagerService管理JAVA應用層所有的service創建與連接(connect)。disconnect,所有的 Activity也是通過這個service來啟動,加載的。ActivityManagerService也是加載在Systems Servcie中的。
Android虛擬機啟動之前系統會先啟動service Manager進程,service Manager打開binder驅動,并通知binder kernel驅動程序這個進程將作為System Service Manager。然后該進程將進入一個循環,等待處理來自其他進程的數據。用戶創建一個System service后,通過defaultServiceManager得到一個遠程ServiceManager的接口。
通過這個接口我們可以調用 addService函數將System service添加到Service Manager進程中,然后client可以通過getService獲取到需要連接的目的Service的IBinder對象。這個IBinder是 Service的BBinder在binder kernel的一個參考,所以service IBinder 在binder kernel中不會存在相同的兩個IBinder對象。
每一個Client進程同樣需要打開Binder驅動程序。對用戶程序而言,我們獲得這個對象就可以通過binder kernel訪問service對象中的方法。Client與Service在不同的進程中,通過這種方式實現了類似線程間的遷移的通信方式,對用戶程序而言當調用Service返回的IBinder接口后,訪問Service中的方法就如同調用自己的函數。
實現接口時有幾個原則:
拋出的異常不要返回給調用者. 跨進程拋異常處理是不可取的。IPC調用是同步的。如果你知道一個IPC服務需要超過幾毫秒的時間才能完成地話,你應該避免在Activity的主線程中調用。
也就是IPC調用會掛起應用程序導致界面失去響應. 這種情況應該考慮單起一個線程來處理,能在AIDL接口中聲明靜態屬性。IPC的調用步驟:
1. 聲明一個接口類型的變量,該接口類型在.aidl文件中定義。
2. 實現ServiceConnection。
3. 調用ApplicationContext.bindService(),并在ServiceConnection實現中進行傳遞.
4. 在ServiceConnection.onServiceConnected()實現中,你會接收一個IBinder實例(被調用的Service). 調用 YourInterfaceName.Stub.asInterface((IBinder)service)將參數轉換YourInterface類型。
5. 調用接口中定義的方法。 你總要檢測到DeadObjectException異常,該異常在連接斷開時被拋出。它只會被遠程方法拋出。
6. 斷開連接,調用接口實例中的ApplicationContext.unbindService()
【編輯推薦】


















