大家都知道Binder機(jī)制主要由ServiceManager绰姻,Binder實(shí)體對(duì)象依溯,Binder代理對(duì)象三個(gè)組件,顧我們想要在Java世界實(shí)現(xiàn)Binder機(jī)制也需要事項(xiàng)這個(gè)三個(gè)組件
Service Manager的Java代理對(duì)象的類型為ServiceManagerProxy
類型温算,想要獲取這個(gè)對(duì)象需要先在C++層創(chuàng)建一個(gè)句柄值為0的Binder代理對(duì)象胆绊,然后在Java層創(chuàng)建一個(gè)對(duì)應(yīng)的Java服務(wù)代理對(duì)象。
最終是ServiceManager類獲取到ServiceManagerProxy對(duì)象颜屠,并保存在了sServiceManager成員變量中辰妙,通過(guò)這個(gè)變量我們又可以得到getService(),listService(),checkService(),addService()
等操作Java服務(wù)的方法。
//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);
}
然后大家會(huì)問(wèn)汽纤?Java服務(wù)代理對(duì)象是從哪里獲取的呢上岗?
看到那個(gè)黃色的小框了沒(méi)有,Java服務(wù)對(duì)象就是通過(guò)JNI方法獲取的
getContextObject()
方法是JNI方法蕴坪,JNI教程參考,它由android_os_BinderInternal_getContextObject來(lái)實(shí)現(xiàn)
//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對(duì)象轉(zhuǎn)換為IBinder對(duì)象的關(guān)鍵方法
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;
}
參數(shù)val要么指向一個(gè)Binder代理對(duì)象肴掷,要么指向一個(gè)Binder本地對(duì)象敬锐。當(dāng)它指向一個(gè)Binder本地對(duì)象時(shí),他的類型為JavaBBinder呆瞻,后者繼承BBinder類台夺。
frameworks/base/libs/binder/Binder.cpp
bool IBinder::checkSubclass(const void* /*subclassID*/) const
{
return false;
}
大家看到checkSubclass是用來(lái)檢測(cè)val指向Binder代理對(duì)象,還是JavaBBinder對(duì)象痴脾,默認(rèn)值返回false颤介。但是JavaBBinder類重寫了其父類BBinder的父類IBinder的成員函數(shù)checkSubclass(),所以只要subclassID
指向全局變量gBinderOffsets
就返回true赞赖。
- 當(dāng)val指向的是一個(gè)JavaBBinder對(duì)象的時(shí)候就返回true滚朵,并通過(guò)成員方法
object()
獲取Java對(duì)象,mobject
指向Java層中的一個(gè)Binder對(duì)象前域。
//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;
}
- 當(dāng)val指向的是一個(gè)句柄值等于0的Binder代理對(duì)象的時(shí)候辕近,它最終返回的是一個(gè)java層的服務(wù)代理對(duì)象,即BinderProxy對(duì)象匿垄。
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);
}
這段代碼的功能主要是檢查當(dāng)前進(jìn)程是否已經(jīng)創(chuàng)建BinderProxy對(duì)象移宅。如果是,則返回指向該BinderProxy對(duì)象的WeakRefenrence對(duì)象object
椿疗。但是object
指向的BinderProxy可能已經(jīng)失效漏峰,因此需要繼續(xù)檢查,并將其升級(jí)為強(qiáng)引用對(duì)象届榄。若object
升級(jí)成功則返回BinderProxy對(duì)象浅乔,如果升級(jí)失敗則解除它與無(wú)效的BinderProxy對(duì)象的對(duì)應(yīng)關(guān)系。
如何將Binder代理對(duì)象與外部對(duì)象關(guān)聯(lián)痒蓬?
例:函數(shù)javaObjectForBinder在為一個(gè)Binder代理對(duì)象(BpBinder)創(chuàng)建一個(gè)Java服務(wù)對(duì)象(BinderProxy)時(shí)童擎,就會(huì)將創(chuàng)建出來(lái)的Java服務(wù)代理對(duì)象(BinderProxy)保存在Binder代理對(duì)象(BpBinder)的成員變量mObjects
中。但是一個(gè)Binder代理對(duì)象(BpBinder)不僅僅是關(guān)聯(lián)一個(gè)外部對(duì)象攻晒,所以需要為每一個(gè)外部對(duì)象設(shè)置一個(gè)參數(shù),而Java服務(wù)代理對(duì)象(BinderPorxy)所使用的參數(shù)就是gBinderProxyOffsets
的地址班挖。
ObjectManager 是定義在BpBinder內(nèi)部的一個(gè)類鲁捏。定義了外部對(duì)象操作函數(shù)attach(增),find(查),detach(刪)。kill函數(shù)用來(lái)清理與Binder代理對(duì)象管理的外部對(duì)象萧芙。
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; // 指向外部對(duì)象的一個(gè)弱引用對(duì)象
void* cleanupCookie; //fun所指向的清理函數(shù)的一個(gè)調(diào)用參數(shù)
IBinder::object_cleanup_func func; // 函數(shù)指針给梅,用來(lái)清理Object指向的外部對(duì)象
};
//維護(hù)與一個(gè)Binder代理對(duì)象所關(guān)聯(lián)的外部對(duì)象,這些外部對(duì)象都使用entry_t結(jié)構(gòu)體來(lái)描述
KeyedVector<const void*, entry_t> mObjects;
相應(yīng)的Binder代理對(duì)象也提供了三個(gè)成員函數(shù)双揪,attchObject动羽,findObject,detachObject用來(lái)增查刪與它關(guān)聯(lián)的外部對(duì)象渔期,具體實(shí)現(xiàn)是調(diào)用內(nèi)部類的成員變量mObjects的成員函數(shù)attach运吓,find渴邦,detach實(shí)現(xiàn)。
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系統(tǒng)源代碼情景分析》