大家都知道Binder机制主要由ServiceManager,Binder实体对象,Binder代理对象三个组件,顾我们想要在Java世界实现Binder机制也需要事项这个三个组件
Service Manager的Java代理对象的类型为ServiceManagerProxy
类型,想要获取这个对象需要先在C++层创建一个句柄值为0的Binder代理对象,然后在Java层创建一个对应的Java服务代理对象。
最终是ServiceManager类获取到ServiceManagerProxy对象,并保存在了sServiceManager成员变量中,通过这个变量我们又可以得到getService(),listService(),checkService(),addService()
等操作Java服务的方法。
//framworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
//framworks/base/core/java/android/os/ServiceManagerNative.java
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);
}
然后大家会问?Java服务代理对象是从哪里获取的呢?
看到那个黄色的小框了没有,Java服务对象就是通过JNI方法获取的
getContextObject()
方法是JNI方法,JNI教程参考,它由android_os_BinderInternal_getContextObject来实现
//framworks/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);
}
然后我们需要具体解析的javaObjectForIBinder()
,看名字就知道他就是将Java对象转换为IBinder对象的关键方法
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?
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);
}
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.
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)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->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;
}
参数val要么指向一个Binder代理对象,要么指向一个Binder本地对象。当它指向一个Binder本地对象时,他的类型为JavaBBinder,后者继承BBinder类。
frameworks/base/libs/binder/Binder.cpp
bool IBinder::checkSubclass(const void* /*subclassID*/) const
{
return false;
}
大家看到checkSubclass是用来检测val指向Binder代理对象,还是JavaBBinder对象,默认值返回false。但是JavaBBinder类重写了其父类BBinder的父类IBinder的成员函数checkSubclass(),所以只要subclassID
指向全局变量gBinderOffsets
就返回true。
- 当val指向的是一个JavaBBinder对象的时候就返回true,并通过成员方法
object()
获取Java对象,mobject
指向Java层中的一个Binder对象。
//framworks/base/core/jni/android_util_Binder.cpp
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
bool checkSubclass(const void* subclassID) const
{
return subclassID == &gBinderOffsets;
}
jobject object() const
{
return mObject;
}
......
private:
jobject const mObject;
}
- 当val指向的是一个句柄值等于0的Binder代理对象的时候,它最终返回的是一个java层的服务代理对象,即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对象。如果是,则返回指向该BinderProxy对象的WeakRefenrence对象object
。但是object
指向的BinderProxy可能已经失效,因此需要继续检查,并将其升级为强引用对象。若object
升级成功则返回BinderProxy对象,如果升级失败则解除它与无效的BinderProxy对象的对应关系。
如何将Binder代理对象与外部对象关联?
例:函数javaObjectForBinder在为一个Binder代理对象(BpBinder)创建一个Java服务对象(BinderProxy)时,就会将创建出来的Java服务代理对象(BinderProxy)保存在Binder代理对象(BpBinder)的成员变量mObjects
中。但是一个Binder代理对象(BpBinder)不仅仅是关联一个外部对象,所以需要为每一个外部对象设置一个参数,而Java服务代理对象(BinderPorxy)所使用的参数就是gBinderProxyOffsets
的地址。
ObjectManager 是定义在BpBinder内部的一个类。定义了外部对象操作函数attach(增),find(查),detach(删)。kill函数用来清理与Binder代理对象管理的外部对象。
class ObjectManager
{
public:
ObjectManager();
~ObjectManager();
void attach( const void* objectID,
void* object,
void* cleanupCookie,
IBinder::object_cleanup_func func);
void* find(const void* objectID) const;
void detach(const void* objectID);
void kill();
private:
ObjectManager(const ObjectManager&);
ObjectManager& operator=(const ObjectManager&);
struct entry_t
{
void* object; // 指向外部对象的一个弱引用对象
void* cleanupCookie; //fun所指向的清理函数的一个调用参数
IBinder::object_cleanup_func func; // 函数指针,用来清理Object指向的外部对象
};
//维护与一个Binder代理对象所关联的外部对象,这些外部对象都使用entry_t结构体来描述
KeyedVector<const void*, entry_t> mObjects;
相应的Binder代理对象也提供了三个成员函数,attchObject,findObject,detachObject用来增查删与它关联的外部对象,具体实现是调用内部类的成员变量mObjects的成员函数attach,find,detach实现。
void BpBinder::attachObject(
const void* objectID, void* object, void* cleanupCookie,
object_cleanup_func func)
{
AutoMutex _l(mLock);
ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
mObjects.attach(objectID, object, cleanupCookie, func);
}
void* BpBinder::findObject(const void* objectID) const
{
AutoMutex _l(mLock);
return mObjects.find(objectID);
}
void BpBinder::detachObject(const void* objectID)
{
AutoMutex _l(mLock);
mObjects.detach(objectID);
}
参考:
《Android系统源代码情景分析》