Binder算是Android中比較難懂的一部分內容了,但是非常的重要,要想研究Framework層無論如何也繞不開Binder。網上也有很多講解Binder的文章,有的很深入涉及到底層C層面,理解起來難度較大,要完全理解還需要Linux驅動的知識,看了還也是似懂非懂,我認為也不需要理解那么深入。寫這篇博客主要是我從最學習理解Binder的過程的角度出發,也來談談Binder。
Binder是什么
Binder是android中用于進程間通信IPC的重要機制,ActivityManagerService、WinderManagerService等系統服務的背后都是Binder。
Binder架構包括服務器接口、Binder驅動、客戶端接口三個模塊。
Binder服務端:一個Binder服務端實際上就是Binder類的對象,該對象一旦創建,內部則會啟動一個隱藏線程,會接收Binder驅動發送的消息,收到消息后,會執行Binder對象中的onTransact()函數,并按照該函數的參數執行不同的服務器端代碼。onTransact函數的參數是客戶端調用transact函數的輸入。
Binder驅動:任意一個服務端Binder對象被創建時,同時會在Binder驅動中創建一個mRemote對象,該對象也是一個Binder類。客戶端訪問遠程服務端都是通過該mRemote對象。
客戶端:獲取遠程服務在Binder驅動中對應的mRemote引用,然后調用它的transact方法即可向服務端發送消息。
這幅圖展現了Binder框架的大致構成,至于里面有一些內容需要看完這篇博客才能看懂。
需要注意的一個問題:既然客戶端要通過mRemote引用調用它的transact方法向服務端發送消息,那么客戶端獲取遠程服務在Binder中的mRemote引用?
客戶端獲取遠程服務在Binder中的mRemote引用有兩種方式:系統服務和自定義的服務端程序不一樣,對于系統服務使用Binder就可以實現服務端,而我們自定義的服務必須借助Service來編寫。
》》系統服務是在系統啟動的時候在SystemServer進程的init2函數中啟動ServerThread線程,在這個線程中啟動了各種服務,并且通過調用ServerManager.addService(String name, IBinder service)將其加入保存起來。ServerManager就相當于DNS服務器,在查找某個服務時通過調用ServerManager.getService(String name)函數就可以獲得遠程服務的Binder,至于它的具體細節可以查看Android啟動相關的源代碼。
》》自定義的服務必須通過Service來實現。
通過bind函數綁定一個遠程服務
[java] view plaincopy
public boolean bindService(Intent service, ServiceConnection conn, int flags)
其中第二個參數是一個回調接口,onServiceConnected的參數service即為遠程服務在Binder驅動中的binder引用。
[java] view plaincopy
public interface ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service);
public void onServiceDisconnected(ComponentName name);
}
使用Binder進行IPC通信
實現如下效果:Activity‘中有一個按鈕,點擊該按鈕,將abc和def三個字母拼接起來,拼接的函數在另一個進程中。
客戶端
[java] view plaincopy
public class MainActivity extends Activity {
private boolean isBound;
private Button btn_add;
private IBinder mRemote = null;
private ServiceConnection serviceConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mRemote = service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bind();
btn_add = (Button)findViewById(R.id.btn_add);
btn_add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String result = null;
try {
result = strcat("abc", "def");
} catch (RemoteException e) {
Toast.makeText(MainActivity.this, "error", 0).show();
e.printStackTrace();
}
Toast.makeText(MainActivity.this, result, 0).show();
}
});
}
private void bind() {
Intent intent = new Intent(MainActivity.this, ComputeService.class);
isBound = bindService(intent, serviceConn, Context.BIND_AUTO_CREATE);
}
private void unbind() {
if (isBound) {
MainActivity.this.unbindService(serviceConn);
isBound = false;
}
}
private String strcat(String x, String y) throws RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
String _result;
try {
_data.writeString(x);
_data.writeString(y);
mRemote.transact(1, _data, _reply, 0);
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
protected void onDestroy() {
unbind();
super.onDestroy();
}
}
遠程服務端
[java] view plaincopy
public class ComputeService extends Service {
private IBinder binder = new Binder(){
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (code == 1) {
String _arg0;
_arg0 = data.readString();
String _arg1;
_arg1 = data.readString();
String _result = this.strcat(_arg0, _arg1);
reply.writeString(_result);
return true;
}
return super.onTransact(code, data, reply, flags);
};
public String strcat(String x, String y){
return x + y;
}
};
@Override
public IBinder onBind(Intent arg0) {
return binder;
}
}
將該service配置在一個新的進程中
[html] view plaincopy
<service android:name = "org.qhyuan.binder.ComputeService"
android:process=":remote"/>
點擊按鈕如圖所示彈出提示
接下來分析上面的代碼:
客戶端通過bindService啟動遠程服務。最終會由系統回調傳入的ServiceConnection接口,因此可以在onServiceConnected函數中獲得該遠程服務所對應的Binder驅動中的引用,接下來想要和遠程服務端通信只需調用該mRemote的transact方法即可。
[java] view plaincopy
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException;
code標識要執行的動作,其實就是指調用服務端的哪個函數。
data是對輸入參數的打包
reply是對返回值的打包
writeString<--->readString 客戶端打包一個Parcel對象,在服務端讀取該Parcel對象中打包的數據,客戶端的寫入和服務端的讀取時對應的。
這里存在的問題:要統一客戶端寫入和服務端讀取的順序,當然對于一個程序員來說,保證這一點是很簡單的。
接下來調用mRemote的transact方法會陷入內核態,也就是說剩下的都是由系統完成的,binder驅動會掛起當前線程,將參數包裹發給服務端程序,在服務端的onTransact(code, data, reply, flags)函數里面讀取出包裝的數據進行處理(數據處理的過程也就是根據code執行指定的服務函數),然后把執行的結果放入客戶端提供的reply包裹中,然后服務端向Binder驅動發送一個notify消息,喚醒客戶端線程,繼續執行使得客戶端線程從Binder驅動返回到客戶端代碼區,再次回到用戶態。
使用AIDL
我們也看到了上面使用Binder進行IPC通信的時候代碼比較繁瑣,尤其是客戶端給服務端發送消息的打包過程中要保證順序的一致性。當然android也給我們提供了一個比較好的方式,那就是使用android提供的aidl工具。
AIDL(Android Interface Definition Language),編譯器通過*.aidl文件的描述信息生成符合通信協議的Java代碼,我們不需要自己寫這些繁雜的代碼,使用非常方便。只需要建立一個xxx.aidl文件,這時在gen目錄下就會生成對應的java文件
[java] view plaincopy
package org.qhyuan.aidl;
interface ICompute {
String strcat (String x,String y);
}
這樣使用aidl來實現上面的功能就可以很簡單了。于是客戶端代碼
[java] view plaincopy
public class MainActivity extends Activity {
private ICompute compute = null;
private boolean isBound;
private Button btn_add;
private ServiceConnection serviceConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
compute = ICompute.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bind();
btn_add = (Button)findViewById(R.id.btn_add);
btn_add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String result = null;
try {
result = compute.strcat("abc", "def");
} catch (RemoteException e) {
Toast.makeText(MainActivity.this, "error", 0).show();
e.printStackTrace();
}
Toast.makeText(MainActivity.this, result, 0).show();
}
});
}
private void bind() {
Intent intent = new Intent(MainActivity.this, ComputeService.class);
isBound = bindService(intent, serviceConn, Context.BIND_AUTO_CREATE);
}
private void unbind() {
if (isBound) {
MainActivity.this.unbindService(serviceConn);
isBound = false;
}
}
@Override
protected void onDestroy() {
unbind();
super.onDestroy();
}
}
服務端代碼
[java] view plaincopy
public class ComputeService extends Service {
private IBinder binder = new ICompute.Stub() {
@Override
public String strcat(String x, String y) throws RemoteException {
return x+y;
}
};
@Override
public IBinder onBind(Intent arg0) {
return binder;
}
}
其他的都不需要改變,是不是簡單了很多?封裝了底層的細節,使得程序寫起來很優美。之前手動寫的transact函數和重寫的onTransact函數也不見蹤影了。
接下來分析上面的代碼,看看aidl文件到底做了什么,能使得我們編寫程序簡化很多。
[java] view plaincopy
/*
- This file is auto-generated. DO NOT MODIFY.
- Original file: E:\EclipseProject\Binder\src\org\qhyuan\aidl\ICompute.aidl
*/
package org.qhyuan.aidl;
public interface ICompute extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
org.qhyuan.aidl.ICompute {
private static final java.lang.String DESCRIPTOR = "org.qhyuan.aidl.ICompute";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an org.qhyuan.aidl.ICompute interface,
* generating a proxy if needed.
*/
public static org.qhyuan.aidl.ICompute asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof org.qhyuan.aidl.ICompute))) {
return ((org.qhyuan.aidl.ICompute) iin);
}
return new org.qhyuan.aidl.ICompute.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data,
android.os.Parcel reply, int flags)
throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_strcat: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _result = this.strcat(_arg0, _arg1);
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements org.qhyuan.aidl.ICompute {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public java.lang.String strcat(java.lang.String x,
java.lang.String y) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(x);
_data.writeString(y);
mRemote.transact(Stub.TRANSACTION_strcat, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_strcat = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String strcat(java.lang.String x, java.lang.String y)
throws android.os.RemoteException;
}
為了看起來方便,這里存在幾個類及每個類中的屬性和方法大致簡化如下。
[java] view plaincopy
interface ICompute extends IInterface
{
strcat();
static abstract class Stub extends Binder implements ICompute {
static final int TRANSACTION_strcat;
static final String DESCRIPTOR;
static asInterface();
asBinder();
onTransact();
static class Proxy implements ICompute {
IBinder binder;
asBinder();
getInterfaceDescriptor();
strcat();
}
}
}
首先要明白AIDL的主要設計思想。產生的這個類的思想是抽象出了一個接口,接口里面包含我們想實現的strcat方法,于是服務端的Binder來實現這個接口,其實就是這里的Stub類。然后客戶端在獲得了服務端在Binder驅動中的Binder引用mRemote后,通過該引用給遠程服務端發送消息,這是包含在Proxy類的strcat函數中。由于有aidl工具生成的代碼所以包裹中的打包數據的順序都是一致的。
ICompute類中的strcat函數不需要實現,僅僅是提供接口而已,具體的在Stub的子類類和Proxy類中實現。
在Stub子類中具體實現,一般是在服務端程序中的。
在Proxy類中的strcat函數包括對參數的打包和通過Binder驅動中的mRemote調用transact函數向服務端發送包裹,再從reply包裹中讀取出返回值返回。
》》TRANSACTION_strcat:是對函數的編號,由于這里只有一個函數stract,所以只有這一個整型值。
》》DESCRIPTOR:每個Stub類有一個描述符,與它實現的接口有關。
》》onTransact:收到Binder驅動發來的包裹,進行解包,這里面調用了this.strcat(_arg0, _arg1);是非常重要的,實際上是在服務器端實現的類的strcat函數。
》》asInterface:是最重要的一個函數,這是一個靜態方法,是用在客戶端將一個IBinder對象轉化為它實現的接口。
如果能根據DESCRIPTION通過queryLocalInterface查找到的值,就直接返回該值,(如果不是因為是static的,是不是返回this就可以了?)這對應的情況是服務端自己調用該Binder中的服務程序。返回的就是服務端的Binder,接下來的調用就是直接用服務端的Binder調用服務端的程序,不存在IPC。否則就將該IBinder包裝成一個新的類Proxy類,接下來調用Proxy的stract方法實質上是用的Binder驅動中的遠程Binder的引用mRemote來調用的,是IPC。這里,Proxy顧名思義是代理的意思,本地調用就直接返回ICompute接口實際上是當前服務器端的Binder,否則就返回一個代理類,該代理類實現了ICompute,里面封裝的是Binder驅動中的mRemote引用,這樣保證接下來的操作是一致的。
一句話就是說asInterface函數的存在將本地調用和進程間調用綜合在一起了。看到這里有沒有覺得三個類組織的非常巧妙代碼很優美呢。
另,上面三個類如果寫成三個類而不是寫成嵌套類的形式會好理解很多。并且和最開始手工寫的Binder本質上是一致的。
代碼中出現的如下幾個打包的數據可以認為是增加安全性和處理一些其他的問題,沒有也是可以可以的。writeInterfaceToken<--->enforceInterface 客戶端封裝一個String標識,在服務端收到后對比確保該Binder驅動確實是想訪問我。類似的還有writeException<--->readException。
再此基礎上去看系統中一些XXXManager代碼,就會容易很多,里面使用Binder的部分都類似于AIDL產生的那些代碼,本質上就是上面講的Binder進行IPC通信,下面舉例子說明源代碼中使用Binder的地方。
系統服務中的Binder分析
下面以ServiceManager和ActivityManagerService為例來分析。ServiceManager:
前面已經提到過ServiceManager可以認為是DNS,用來查找系統服務。保存了已經開啟的系統服務。他有兩個主要的方法
[java] view plaincopy
public static IBinder getService(String name)
public static void addService(String name, IBinder service)
實際上ServerManager既是系統服務的管理者,同時也是一個系統服務。因此它肯定是基于Binder實現的。
接下來的分析中,時刻記得使用aidl工具生成那三個類:IXXX、IXXX.Stub和IXXX.Stub.Proxy,并做好對應。這樣看ServiceManager的相關的代碼就容易多了。1.與IXXX相對應的類就是IServiceManager類,封裝了遠程調用的幾個主要函數。
[java] view plaincopy
public interface IServiceManager extends IInterface
{
public IBinder getService(String name) throws RemoteException;
public IBinder checkService(String name) throws RemoteException;
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException;
public String[] listServices() throws RemoteException;
public void setPermissionController(IPermissionController controller)
throws RemoteException;
static final String descriptor = "android.os.IServiceManager";
int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;
}
2.與IXXX.Stub對應的類就是ServiceManagerNative。[java] view plaincopy
public abstract class ServiceManagerNative extends Binder implements IServiceManager{
static public IServiceManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
public ServiceManagerNative() {
attachInterface(this, descriptor);
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags){
try {
switch (code) {
case IServiceManager.GET_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = getService(name);
reply.writeStrongBinder(service);
return true;
}
case IServiceManager.ADD_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = data.readStrongBinder();
boolean allowIsolated = data.readInt() != 0;
addService(name, service, allowIsolated);
return true;
}
// ...
} catch (RemoteException e) {
}
return false;
}
public IBinder asBinder() {
return this;
}
}
3.與IXXX.Stub.Proxy對應的類ServiceManagerProxy[java] view plaincopy
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
// ....
private IBinder mRemote;
}
觀察上面的代碼,實際上和使用adil生成的代碼沒什么兩樣。僅僅是類命名不一樣,將三個類分開寫了而已。
不用看源代碼也知道接下來該怎么做了吧?!當然就是在服務端繼承ServiceManagerNative類實現里面的相關方法就能實現服務端,然后在客戶端將遠程服務端所對應的的Binder封裝成IServiceManager iSm = ServiceManagerNative.asInterface(binder)即可,正常情況下確實是這樣的。實際上,在源碼中找不到繼承自ServiceManagerNative類的遠程服務端類,比如說ServiceManagerService,根本就找不到這樣一個類。原因是SMS在native層被實現成一個獨立的進程,是在啟動后解析init.rc腳本啟動服務的。native層的代碼沒必要去研究,那么這個遠程的Binder怎么獲得呢?系統提供的函數BinderInternal.getContextObject()來獲得對應的Binder引用。還是ServiceManager比較特殊嘛,畢竟對于“DNS”來說不得一開機就啟動,還與其他“主機”有點差別,但是其他的系統服務就和上面我們想象的那樣是一樣的了。
這里要說明一點,雖然SMS服務時在native層,獲取遠程服務卻并不一定非要在native層實現,使用Binder構架與是用什么語言沒必然關系。
當然了,這里的ServiceManagerNative確實沒什么用,如果要說有用,就是他的靜態方法asInterface吧。但不知道為什么android源碼中還有這個類的存在,至少這樣讓我們隱約感覺Binder通信的框架就是這樣的,提高了一致性。
接下來我們看ServiceManager類
[java] view plaincopy
public final class ServiceManager {
private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
// 本地有緩存
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
// 其實是IPC調用,具體會調用
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
// ...
}
ServiceManager類其實就是對遠程的SMS服務的Binder的封裝。使用ServiceManagerNative.asInterface(BinderInternal.getContextObject());將其轉化為sServiceManager接口,接下來使用該對象即可完成IPC調用。
舉個例子比如調用ServiceManager的getService方法,實際上會ServiceManagerProxy走到ServiceManagerProxy類的getService方法里面去,然后就是向服務端發消息。當然這些細節就不用考慮了,因為android的Binder機制封裝的就是這么完美,你不用關注底層細節。
ActivityManager:
再看看ActivityManager中的Binder。
IActivityManager對應IXXX接口
ActivityManagerNative對應IXXX.Stub類,繼承自Binder類。
ActivityManagerProxy對應IXXX.Stub.Proxy類。
那么AMS的服務端是那個類呢?沒錯,就是ActivityManagerService類,這個類繼承自ActivityManagerNative,實現了IActivityManager接口中的方法用來進行IPC。
那么只要在客戶端得到了這個遠程服務端的Binder引用就可以進行IPC通信了,事實確實是這樣的。舉個栗子,在ActivityThread的attach方法里有下面兩行代碼
[java] view plaincopy
IActivityManager mgr = ActivityManagerNative.getDefault();
mgr.attachApplication(mAppThread);
而getDefault方法代碼如下
[java] view plaincopy
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
// 這里可以看到通過調用getService方法得到Binder
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
顯然,ActivityManagerNative.getDefault()就可以得到遠程的activity的服務AMS對應的Binder引用,并且調用asInterface將其轉化為IActivityManager,接下來調用接口中的函數即可和遠端的AMS通信。一般來說,對于其他的Service一般就是通過ServiceManager來獲取對應的Binder。
當然,如果還想弄的更清楚點還需要知道這個系統服務是在哪里啟動和將Binder添加到SystemServer中的。
在SystemServerr進程的init2函數中啟動ServerThread線程,這個線程中啟動了很多系統服務,而每個系統服務都是一個線程。ServerThread的run方法大概有1000行,里面啟動了系統服務,不同的服務有不同的啟動方法。
比如這里的AMS是通過調用context = ActivityManagerService.main(factoryTest)實現的。main函數里面啟動了AThread線程。
接下來又調用了ActivityManagerService.setSystemProcess();
[java] view plaincopy
public static void setSystemProcess() {
ActivityManagerService m = mSelf;
ServiceManager.addService("activity", m, true);
ServiceManager.addService("meminfo", new MemBinder(m));
ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
ServiceManager.addService("dbinfo", new DbBinder(m));
// ....
}
這里的m是在AThread線程中new出來的ActivityManagerService實例。至此,就完成了服務的啟動和向ServiceManager中的添加。當然里面有很多細節,這里主要是跟蹤Binder通信的過程。