一、前言
在前一篇中我们知道Binder的使用遍布于应用层的各个组件中,正是Binder支撑起了各大系统服务使得应用可以无边界透明的使用其提供的功能模块。本篇将会介绍在Framework层的IPC完整过程。
在上篇中我们知道四大组件在调用系统Binder Server时存在一个分割线,那就是ActivityManagerNative,以启动activity为例,我们看下具体的代码
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
....
}
在Binder系列开篇中我们介绍了在Android中Binder是一种C/S的架构,Binder Client通过接口进行IPC访问以使用Binder Server的服务,这常常需要跨越多个进程来进行,Android系统为使方便Client端更加方便透明的使用Binder Server一般都提供了Binder Proxy,即Binder代理。
二、Binder 代理
什么是代理呢?举个栗子,比如我的身份证过期了要补办,我这时作为Binder Client要到公安局去办理身份证,这时候公安局就是作为一个Binder Server存在的,我要请求它的服务来更新我的身份证,如果我的户籍地在北京,我本人又在深圳,那么按理来说我要去访问北京公安局提供的服务才能完成更新身份证的业务,但如果北京公安局将办理北京人身份证的服务授权给深圳公安局,那么我就不需要那么麻烦回到北京去办理了,直接在深圳当地公安局办理就完事了,这样深圳公安局扮演的就是代理的角色,在这个例子中,如果我们可以将北京和深圳理解为Binder Server和Binder Client所在的进程,Binder Server即北京公安局在北京,Binder Client(即我本人)和Binder Proxy(即深圳公安局)在深圳,我在深圳本地就能把跨区域的事情办理了,即Binder Client在其进程内部就能完成跨进程的通信。从我的角度来看,这个所谓跨区域是透明的,即我看不到深圳公安局如何和北京公安局的业务往来,我只知道它们之间沟通后就可以将我的身份证补办了。同理,从Binder Client的角度来看,Binder Proxy的存在是Binder能够淡化进程边界的原因。
上面我们提到,Binder Client一般通过Binder代理来和Binder Server进行IPC通信,进行IPC通信的实际过程是由Binder Proxy和Binder Server进行的。在上面的启动activity的例子中,ActivityManagerNative就扮演着这样的角色。
三、Framework层的Binder
为了分析Binder在Framework中的IPC过程,这里具体分析下ActivityManagerNative具体是如何通过Binder来完成IPC过程的。 其他的Binder服务代理原理都是相同的。首先打开ActivityManagerNative的源码,它的位置在 /frameworks/base/core/java/android/app/ActivityManagerNative.java 我们先看看类的继承关系
public abstract class ActivityManagerNative extends Binder implements IActivityManager
ActivityManagerNative继承自Binder,实现了IActivityManager,继承Binder说明它有了成为Binder代理的资格,同时也就具有了Binder提供的IPC能力,实现IActivityManager接口,是ActivityManagerNative是声明了它作为一个Binder代理声明提供了哪些服务,比如startActivity,startService等等
还记得我们怎么使用这个Binder代理的吗?
ActivityManagerNative.getDefault().startActivity(...)
接下来我们看看getDefault中发生了什么
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
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获取到一个IActivityManager的实现对象,它应该是具有IPC能力的。并且这个gDefault是个单例,也就是每个进程都可以有一个AMS的Binder代理。接下里,我们将解开这段简单的代码内部的复杂逻辑实现,揭开它是如何魔术般的完成Binder代理的创建的。
IBinder b = ServiceManager.getService("activity");
在Binder开篇中我们知道ServiceManager作为Binder服务的大管家实际上类似于一个DNS服务器,我们想要获取Binder实名的服务需要先通过它来查取。这里我们是去取AMS的服务,所以传递的参数为activity。在此之前我们需要大概了解下AMS的Binder服务是如何添加到ServiceManger中的,然后再来看这里的查询,下面我们就来了解下ServiceManager。
四、ServiceManager
ServiceManager是Binder服务的大管家,它内部维护了实名Binder的列表,同时由于ServiceManager的特殊性,它在单独的servicemanager系统进程中运行,在系统启动时会启动该进程来完成servicenanager的初始化,下面看看它会做些什么~
//frameworks/native/cmds/servicemanager/service_manager.c
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
//打开binder 这里映射的内存大小为128k
bs = binder_open(128*1024);
//使sm成为所有服务的大管家
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);//binder循环
return 0;
}
servicenanager的初始化是通过binder_become_context_manager该方法来完成的(内部实际是通过ioctl向binder驱动设置BINDER_SET_CONTEXT_MGR来完成大管家的设置),从名称上看它是将通过binder_open打开的虚拟binder设备初始化为一个context manager即服务的大管家,它的句柄即BINDER_SERVICE_MANAGER(被定义为0),随后进入binder_loop循环来监听可能到来的添加或者查询等请求,到这里ServiceManager进程初始化完成。
五、Binder服务的添加
下面看看AMS的Binder实名服务如何添加到servicemanager中,此Binder实体服务创建于system_server进程,因此我们需要看看system_server进程相关代码。system_server进程跑起来会调用java层的SystemServer类的main方法,在该方法中会通过ServerThread的initLoop方法初始化位于system_server进程中的Binder服务实体,并通过ServiceManager.addService将其添加到ServiceManager中管理起来。
//frameworks/base/services/java/com/android/server/SystemServer.java
public void initAndLoop() {
...
Slog.i(TAG, "Telephony Registry");
telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
Slog.i(TAG, "Scheduling Policy");
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
ActivityManagerService.setSystemProcess();
Slog.i(TAG, "Entropy Mixer");
ServiceManager.addService("entropy", new EntropyMixer(context));
...
}
public static void setSystemProcess() {
try {
ActivityManagerService m = mSelf;
ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(m));
....
}
....
}
ServiceManager调用addService方法来完成java层实名服务的添加,这里需要注意,并不是所有的Binder服务都在system_server进程中,也并不是所有的Binder服务都是java层的对象,也有native层的对象直接在native层添加到ServiceManager中,但不管怎么样,最终都要通过native层的servicemanager添加。下面我们看看ServiceManager 添加服务的过程。
/frameworks/base/core/java/android/os/ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
//BinderInternal.getContextObject()实际上获取的即是BpBinder(0),它是SM native层的本地代理
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
//取到SM的java层的本地代理对象ServiceManagerProxy,通过这个代理对象可将java层的Service作为Binder实体添加到SM中
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);
}
首先需要通过ServiceManagerNative拿到ServiceManager的代理,别忘记ServiceMager它作为一个服务大管家,它同样是一个Binder Server,单独的存在于servicemanager进程中。而通过BinderInternal.getContextObject()(它是一个native方法)去获取Binder Server的binder代理对象,然后通过ServiceManagerNative将其转换为ServiceManager的binder代理。
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
可以看到通过ProcessState的getContextObject(参数为NULL表示获取ServiceManager的Binder代理)获取到了IBinder,它是native的代理Binder,随后通过javaObjectForIBinder将其转换为java层的代理Binder。
通过ServiceManager的binder代理,我们可以看看java层的实名Binder服务是如何添加到ServiceManager的
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
//添加Java层的实名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);//将service写入到Parcel中
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
...
}
这里的mRemote即SM的Binder代理对象,它负责和实名的Binder Server进行通信,注意此时的进程边界,mRemote是在system_server进程中的,而它对应的实名Binder Server在servicemanager进程中。在addService中我们将实名binder的name和Binder对象写入到Parcel中通过mRemote发送给servicemanager进程中的实体Binder对象。关于Parcel后续再进行介绍,我们只需了解它用于Binder IPC间的数据通信即可。对于java层的Binder实体,它在加入到Parcel中将其转换为native的binder,这是在Parcel的writeStrongBinder中进行的。
//jni 写强引用的binder到parcel中
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
//这里先通过ibinderForJavaObject(定义在android_util_Binder中)将java层的binder对象转换为native层的binder
//实际上就是将上层的service实体转换为JavaBBinder
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
ibinderForJavaObject首先将java层的IBinder转换为native层的对象,然后再写入到Parcel中。
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetIntField(obj, gBinderOffsets.mObject);//从Binder的mObject取出JavaBBinderHolder实体
return jbh != NULL ? jbh->get(env, obj) : NULL;//在这里第一次调用了JavaBBinderHolder的get
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
java层的Binder Server最终都要继承自Binder对象,再Binder类的内部有一个mObject成员,它再Binder构造时通过native init方法创建,实际上它是一个JavaBBinderHolder对象,即持有一个JavaBBinder,这个JavaBBinder是什么东西呢?它实际上就是java层的Binder Server实体对象在native层的对象。在ibinderForJavaObject,首先从java层的Binder对象中取到该对象,然后通过调用其get方法获得内部的JavaBBinder,这样java层的Binder实体对象就被转换native层的JavaBBinder,随后写入到Parcel中,通过servermanager记录下来。关于servicemanager如何具体处理接收到的binder对象,这里暂不展开介绍。
六、Binder服务的查询
通过ServiceManager的binder代理,我们可以通过ServiceManager.getService("activity")获取到AMS的代理对象IBinder,这里我们顺便看看servicemanager是如何在native层查询该binder代理服务的。可以知道它同样是由ServiceManagerProxy完成的。
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;
}
获取实名Binder的代理需要告知其name,通过该name,servicemanager查询内部列表,将查找到的native binder proxy转换为java层的IBinder即可获取到该Binder实名对象在java层的代理。
七、Binder代理在java层的转换
同获取ServiceManager的binder代理类似,事实上,我们通过ServiceManager.getService("activity")拿到的实际上就已经是ServiceManager提供给上层的Binder代理了,只是相比ServiceManager的native层,这里我们是通过servicemanager的代理Binder拿到AMS的binder代理,而ServiceManager的代理是通过ProcessState获取到的,因为它的句柄是已知的即NULL。即该binder对象具有和Binder服务实体进行IPC通信的能力,即我们在应用进程中通过该binder可以和AMS进程通信,而IActivityManager am = asInterface(b)是将这种IPC的能力转换成对应的AMS接口的形式以方便调用。我们看看它的实现
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
class ActivityManagerProxy implements IActivityManager
{
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public IBinder asBinder()
{
return mRemote;
}
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, String profileFile,
ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
...
}
...
}
我们看到这里通过我们获取的binder代理创建了一个ActivityManagerProxy对象,ActivityManagerProxy实现了ActivityManagerService服务声明的接口,它内部实际是通过前面获取的代理IBinder完成的。所以ActivityManagerService的服务代理Binder可以看作是ActivityManagerProxy对象,在这里即为IActivityManager。
八、Binder代理在native层的转换
我们知道native层的binder代理要在java层使用需要先转换为java的Binder代理对象IBinder,此对象具有IPC的能力。在了解ServiceManager时我们知道它是通过javaObjectForIBinder来获取到的。
/frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
/frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
return getStrongProxyForHandle(0);//0为SM的Binder句柄
}
//根据Binder句柄获取IBinder,即BpBinder,它负责和Binder实体进行通信
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
b = new BpBinder(handle); //为要请求的远端服务创建一个BpBinder代理
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
可以看到ServiceManager的本地代理对象是通过getStrongProxyForHandle在内部创建了一个BpBinder对象,这个对象即native层的binder。
下面看看AMS的native层的binder代理是如何创建的,我们知道通过ServiceManagerProxy的getService获取到java层的Binder代理,而它是从servicemanager的Binder返回的Parcel中读取到。因此我们看看servicemanager的是如何获取到binder对象的。
int svcmgr_handler(struct binder_state *bs,
struct binder_txn *txn,
struct binder_io *msg,
struct binder_io *reply)
{
struct svcinfo *si;
uint16_t *s;
...
strict_policy = bio_get_uint32(msg);//取到policy值
s = bio_get_string16(msg, &len);//取到interface 即android.os.IServiceManager
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);//获取要查询的service的名称
ptr = do_find_service(bs, s, len, txn->sender_euid);
if (!ptr)
break;
bio_put_ref(reply, ptr);
return 0;
}
}
servicemanager将GET_SERVICE_TRANSACTION的请求转发给svcmgr_handler进行处理,在SVC_MGR_GET_SERVICE分支下,这里首先通过bio_get_string16查询到service的名称,然后通过do_find_service获取到binder server对象,并将其通过bio_put_ref打包到reply对应的binder_io中,最后通过binder发送给servicemanager对应的BpBinder对象。对于SM的getService方法,我们知道它内部调用了SM的Binder Proxy的getService方法,在getService方法内部又通过mRemote的transact方法发起向SM实体Binder的请求,实际上也即是通过SM对应的native端的Binder代理对象BpBinder发起的。我们看看它的实现是怎么样的。
//这是BpBinder最重要的方法,该方法用来和远程Service进行通信
frameworks/native/libs/binder/BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
//将数据发送给Binder驱动 注意这里的mHandler代表了具体服务的句柄
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
ServiceManager通过BpBinder的transact和servicemanager的实体Binder server进行通信,它内部会使用IPCThreadState 对象的transact方法进行处理。
//BpBinder通过该方法和服务端进行通信
frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
...
if (err == NO_ERROR) {
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
//将要发送的数据打包到mOut中 Parcel->binder_transaction_data,这里的cmd为BC_TRANSACTION
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
//TF_ONE_WAY未设置,表示同步调用
if ((flags & TF_ONE_WAY) == 0) {
#if 0
if (code == 4) { // relayout
ALOGI(">>>>>> CALLING transaction 4");
} else {
ALOGI(">>>>>> CALLING transaction %d", code);
}
#endif
//同步等待返回结果
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
...
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
当transact结束后,ServiceManager的代理Binder就可以从reply的Parcel对象中拿到读取获取的binder代理对象了。
九、native代理对象转换
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;
}
通过SM代理对象的getService方法,最终从reply的Parcel中读取到IBinder对象,这个IBinder对象即使name对应的Binder Server在java层的Binder代理对象,那么这个对象到底是如何创建的呢?我们需要进一步分析Parcel的readStrongBinder方法。
//从Parcel中读取Binder对象
/frameworks/base/core/jni/android_os_Parcel.cpp
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr)
{
//取到native层的Parcel对象
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
//readStrongBinder负责从Parcel中读取到Binder对象,实际上就是BpBinder,并通过javaObjectForIBinder构造
//BinderProxy对象
return javaObjectForIBinder(env, parcel->readStrongBinder());//实际上返回的是一个BinderProxy实例
}
return NULL;
}
在android_os_Parcel_readStrongBinder方法中nativePtr对应的是reply在natvie层的对象地址,先将其转换为native层的Parcel对象,然后native层的readStrongBinder获取到native层的Binder代理,最后通过javaObjectForIBinder将其转换为java层的IBinder对象。
/frameworks/native/libs/binder/Parcel.cpp
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
unflatten_binder(ProcessState::self(), *this, &val);
return val;
}
//这个方法同flatten_binder是相对的 目的是从Parce中读取binder对象返回
status_t unflatten_binder(const sp<ProcessState>& proc,
const Parcel& in, sp<IBinder>* out)
{
const flat_binder_object* flat = in.readObject(false);//先读取对象结构
if (flat) {
switch (flat->type) {//判断类型
case BINDER_TYPE_BINDER://对于同一个进程的时候 type应为BINDER_TYPE_BINDER
//如果是本地的进程,则flat->cookie保存了binder对象也就是BBinder,也是服务本身
*out = static_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
//否则是远程的对象,通过ProcessState的getStrongProxyForHandle获取服务的代理binder
//BpBinder,这里传入的handle会传递给BpBinder,这样BpBinder就可以通过这个handle
//和服务端进行通信了
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast<BpBinder*>(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
readStrongBinder内部调用unflatten_binder方法来获取到IBinder对象,内部先读取到flat_binder_object结构,其type对应于BINDER_TYPE_HANDLE表示是binder的句柄,这个句柄值是由binder驱动根据其binder server为定义和维护的。这里通过ProcessState的getStrongProxyForHandle来为其创建native的IBinder代理,我们进一步分析其内部实现。
//根据Binder句柄获取IBinder,即BpBinder,它负责和Binder实体进行通信
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
b = new BpBinder(handle); //为要请求的远端服务创建一个BpBinder代理
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
从getStrongProxyForHandle的实现来看,它内部实际是创建BpBinder,从方法名也可以看出该方法就是通过handle值来获取到对应的Binder代理,到这里创建native Binder代理对象的任务完成了,接下里看看这个对象是如何被转换为java层的IBinder对象的。前面我们知道,这是通过javaObjectForIBinder完成的。
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
// For the rest of the function we will hold this lock, to serialize
// looking/creation of Java proxies for native Binder proxies.
AutoMutex _l(mProxyLock);
// Someone else's... do we know about it?
//取到BinderProxy的类信息
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {
jobject res = jniGetReferent(env, object);
if (res != NULL) {
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//创建一个BinderProxy的实例
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object.
//将BpBinder保存在BinderProxy实例的mObject中
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
val->incStrong((void*)javaObjectForIBinder);
// The native object needs to hold a weak reference back to the
// proxy, so we can retrieve the same proxy if it is still active.
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
// Also remember the death recipients registered on this proxy
sp<DeathRecipientList> drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;//返回BinderProxy实例
}
这个方法实际上为java层的代理提供,在native层取到BpBinder后,会通过BpBinder来构造java层的BinderProxy,这里会将BpBinder设置到BinderProxy的mObject中,这样service的 Proxy就可以通过BinderProxy来和其服务进行通信了,那么这个BinderProxy是什么呢?它的定义如下:
final class BinderProxy implements IBinder {
private int mObject;//这里持有的实际上就是用于Binder Client端的BpBinder
....
}
从名称看它是java层的Binder Proxy,它实现了IBinder接口,最终返回给java层的IBinder正是它,但它都是以IBinder的形式使用的。
总结
到这里我们就介绍完关于实名Binder及其代理的大多数内容,简单的总结下,java层的Binder Client要与Binder Server通信都要通过其代理进行IPC,代理在java层是以BinderProxy的形式存在,在native层是以BpBinder的形式存在,当通过getService获取Binder代理时,Parcel内部会将通过句柄值来构造BpBinder对象。java层的BinderProxy在native层实际上为BpBinder,即无论java层和native层代理是一致的都是BpBinder。BpBinder是Binder实体的代理人,它们一般在不同的进程中,Binder Client在获取到IBinder对象后(内部为BpBinder),即有了IPC的能力后,会通过此构造其接口代理对象,如AMS的ActivityManagerProxy,它内部的mRemote即是具有IPC能力的IBinder对象。