Android-Framework:Binder全解析(三)这篇看完还不懂

这是函数原型:

//原型
/*
addr: 代表映射到进程地址空间的起始地址,当值等于0则由内核选择合适地址,此处为0;
size: 代表需要映射的内存地址空间的大小,此处为1M-8K;
prot: 代表内存映射区的读写等属性值,此处为PROT_READ(可读取);
flags: 标志位,此处为MAP_PRIVATE(私有映射,多进程间不共享内容的改变)和 MAP_NORESERVE(不保留交换空间)
fd: 代表mmap所关联的文件描述符,此处为mDriverFD;
offset:偏移量,此处为0。

此处 mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
/
void
mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset)

总的来说,ProcessState做了两件事情,一是打开Binder驱动并返回文件操作符fd,二是通过mmap为Binder分配了一块虚拟内存空间,以达到内存映射的目的。

得到ProcessState对象后,调用它的getContextObject方法得到BpBinder对象。

ProcessState.getContextObject

//frameworks/native/libs/binder/ProcessState.cpp
sp ProcessState::getContextObject(const sp& /caller/)
{
return getStrongProxyForHandle(0); //
}

在之前的篇幅中讲了,当请求服务的进程的handler是0的时候就是获取ServiceManager的BpBinder对象。这里的话就是获取获取handle=0的IBinder。

ProcessState.getStrongProxyForHandle

//frameworks/native/libs/binder/ProcessState.cpp
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp result;

AutoMutex _l(mLock);
//查找handle对应的资源项
handle_entry* e = lookupHandleLocked(handle);

if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
//通过ping操作测试binder是否准备就绪
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
//当handle值所对应的IBinder不存在或弱引用无效时,则创建BpBinder对象
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}

首先查找handler所对应的资源,当handle值所对应的IBinder不存在或弱引用无效时会创建BpBinder,否则直接获取。handle==0的特殊情况,即获取的是ServiceManager,需要通过PING_TRANSACTION来判断是否准备就绪。

创建BpBinder

//frameworks/native/libs/binder/BpBinder.cpp
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK); //延长对象的生命时间
IPCThreadState::self()->incWeakHandle(handle); //handle所对应的bindle弱引用 + 1
}

创建BpBinder对象中会将handle相对应Binder的弱引用增加1.

创建完成以后我们就重新回到了getContextObject()方法中

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}

可以看到,使用了javaObjectForIBinder方法将本地IBinder指针转为javaobject。然后返回给了Java层。

javaObjectForIBinder

//frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env, const sp& val) {
if (val == NULL) return NULL;

if (val->checkSubclass(&gBinderOffsets)) { //返回false
jobject object = static_cast<JavaBBinder*>(val.get())->object();
return object;
}

AutoMutex _l(mProxyLock);

jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) { //第一次object为null
jobject res = jniGetReferent(env, object);
if (res != NULL) {
return res;
}
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}

//创建BinderProxy对象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
//BinderProxy.mObject成员变量记录BpBinder对象
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
val->incStrong((void*)javaObjectForIBinder);

jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
//将BinderProxy对象信息附加到BpBinder的成员变量mObjects中
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);

sp drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
//BinderProxy.mOrgue成员变量记录死亡通知对象
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(drl.get()));

android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;
}

根据BpBinder(C++)生成BinderProxy(Java)对象. 主要工作是创建BinderProxy对象,并把BpBinder对象地址保存到BinderProxy.mObject成员变量. ,实现了proxy拥有了native对象的引用。通过BpBinder的成员变量mObjects记录BinderProxy对象信息, 实现了native对象需要保存proxy对象的弱引用,当proxy还存在的时候,可以检索到同一个proxy。到此,可知ServiceManagerNative.asInterface(BinderInternal.getContextObject()) 等价于

ServiceManagerNative.asInterface(new BinderProxy())

ServiceManagerNative.asInterface方法中:

static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) { //obj为BpBinder
return null;
}
//由于obj为BpBinder,该方法默认返回null
IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj); //
}

由此,可知ServiceManagerNative.asInterface(new BinderProxy()) 等价于new ServiceManagerProxy(new BinderProxy()).

ServiceManagerProxy初始化

class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}

mRemoteBinderProxy对象,该BinderProxy对象对应于BpBinder(0),其作为binder代理端,指向native层大管家service Manager。

ServiceManager.getIServiceManager最终等价于new ServiceManagerProxy(new BinderProxy())

framework层的ServiceManager的调用实际的工作确实交给ServiceManagerProxy的成员变量BinderProxy;而BinderProxy通过jni方式,最终会调用BpBinder对象;可见上层binder架构的核心功能依赖native架构的服务来完成的。

参考:gityuan

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值