前言:
1.Binder是什么?
2.Binder的原理是什么?
3.Binder如何實(shí)現(xiàn)?
1.Binder是什么?
Binder是Anroid平臺跨進(jìn)程通信的一種重要的實(shí)現(xiàn)方式(
另外三種:
- Messenger
- broadcast
- socket
),是Google基于OpenBinder實(shí)現(xiàn)的進(jìn)程間通信的驅(qū)動(dòng)程序框架, 由于Android是每個(gè)應(yīng)用或者服務(wù)(AMS,IMS)都運(yùn)行在一個(gè)獨(dú)立的進(jìn)程,每個(gè)進(jìn)程之間的數(shù)據(jù)是獨(dú)立的,想要通信就需要一種跨進(jìn)程的技術(shù).
2.Binder的原理是什么?
2.2 Binder對應(yīng)的驅(qū)動(dòng)設(shè)備文件為:/dev/binder.
- 2.2.1通過Client/Service模式 : C/S之間維護(hù)一個(gè)線程池進(jìn)程通信,通過dev/binder該設(shè)備文件調(diào)用內(nèi)核中的bingder驅(qū)動(dòng)程序
2.2.1.1.Client組件對應(yīng)的是BnInterface,描述本地binder對象,service組件對應(yīng)的是BpInterface。描述本地binder代理對象.
2.2.1.2系統(tǒng)定義了IBinder接口,其中Binder和BinderProxy分別實(shí)現(xiàn)了IBinder接口,前者代表服務(wù)端Bn,而后者代表客戶端Bp.
- 2.2.2 Binder進(jìn)行進(jìn)程間通信: 首先要調(diào)用open函數(shù)打開設(shè)備文件dev/binder獲得文件描述符,再調(diào)用mmp將該描述符映射到內(nèi)核地址空間,然后分配內(nèi)核緩沖區(qū),該緩沖區(qū)是用來傳遞數(shù)據(jù)的,才能通過這個(gè)和binder驅(qū)動(dòng)程序交互。
2.3 .
Android應(yīng)用層系統(tǒng)想啟動(dòng)另外一個(gè)進(jìn)程里面的service或者activity等組件,最終都是通過一個(gè)遠(yuǎn)程的mRemote Binder對象去跨進(jìn)程通信想AMS發(fā)送一個(gè)請求啟動(dòng),下面通過分析AMS來分析Binder的原理。
其中AMS的繼承方式:
ActivityManagerService ->ActivityManagerService->Binder
public ActivityManagerNative() {
attachInterface(this, descriptor);
}
/**
* Convenience method for associating a specific interface with the Binder.
* After calling, queryLocalInterface() will be implemented for you
* to return the given owner IInterface when the corresponding
* descriptor is requested.
*/
public void attachInterface(IInterface owner, String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
//from IActivityManager
String descriptor = "android.app.IActivityManager";
當(dāng)啟動(dòng)一個(gè)Activity的流程為:
Activity.java:
public void startActivityForResult(Intent intent, int requestCode,@Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
}
Instrumentation.java:
public void execStartActivitiesAsUser() {
int result = ActivityManagerNative.getDefault()
.startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,
token, options, userId);
}
ActivityManagerNative.java:
/**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
//
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
//拿到對應(yīng)的ServiceManaerService
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;
}
。
。
。
}
}
其中g(shù)Default最終拿到的是一個(gè)面向底層的客戶端BinderProxy對象(ActivityManagerProxy)
從上面代碼可以看出最終是調(diào)用AMN的startActivity方法。
但是該Binder客戶端對象就是是跟底層那個(gè)目標(biāo)通信呢?
ServiceManager.getService("activity");
/**
* Returns a reference to a service with the given name.
*
* @param name the name of the service to get
* @return a reference to the service, or <code>null</code> if the service doesn't exist
*/
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
/**
* Return the global "context object" of the system. This is usually
* an implementation of IServiceManager, which you can use to find
* other services.
*/
public static final native IBinder getContextObject();
從上面可以知道getContextObject返回了一個(gè)指向地城ServiceManager的Native BinderProxy對象,并且在JAVA層封裝 起來給JAVA調(diào)用,如下:
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
*/
//其中obj就是上面?zhèn)鬟M(jìn)來指向Native BinderProxy對象的地址。
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);
}
上面ServiceManagerProxy對象就是封裝了在BinderInternal拿到的Native對象的。
下面通過分析getService方法,分析客戶端發(fā)送請求過程:
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;
}
//其中mRemote就是BinderInternal. getContextObjectd的navtive對象。
也就是說,將數(shù)據(jù)封裝成Parcel對象,然后通過native binder發(fā)起請求。
上面是客戶端的請求。
ActivityManagerService.java:
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
上面是AMS實(shí)現(xiàn)的接受到客戶端請求的實(shí)現(xiàn)方法。
我們知道AMS是繼承Binder,當(dāng)?shù)讓邮盏秸埱笫?,最終會(huì)調(diào)用Binder.java對應(yīng)的方法:
// Entry point from android_util_Binder.cpp's onTransact
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
// Log any exceptions as warnings, don't silently suppress them.
// If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
try {
res = onTransact(code, data, reply, flags);
}
其中onTransact是一個(gè)抽象方法,其中AMS上面實(shí)現(xiàn)了該方法,完成請求。
流程如圖:

后記:JAVA中搭建了一整套框架,如IBinder接口,Binder類,和BiindeProxy(如ServiceManagerProxy)其中本質(zhì)就是向binder驅(qū)動(dòng)發(fā)送請求或者接受回復(fù)。
即使不使用JAVA的框架,也是可以實(shí)現(xiàn),比如ServiceManager作為Binder的一個(gè)核心程序,就是直接讀取/dev/binder設(shè)備。