这是函数原型:
//原型
/*
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;
}
}
mRemote
为BinderProxy
对象,该BinderProxy
对象对应于BpBinder(0),其作为binder代理端,指向native层大管家service Manager。
ServiceManager.getIServiceManager
最终等价于new ServiceManagerProxy(new BinderProxy())
framework层的ServiceManager
的调用实际的工作确实交给ServiceManagerProxy
的成员变量BinderProxy
;而BinderProxy
通过jni方式,最终会调用BpBinder
对象;可见上层binder架构的核心功能依赖native架构的服务来完成的。
参考:gityuan