Binder-到底是本地Binder还是BinderProxy

到底是Binder还是BinderProxy,this is a question

如果是自己写的service是统一进程是Binder,也就是直接调用,这个在编译后生成的IXXXX.java的asInterface中能看到

如果调用系统的service,显然是跨进程的,是BinderProxy,这里也是在asInterface中转换的。这个流程就是很绕了,是native的BpBinder转化成的java层的BinderProxy

具体流程:

1.service会注册到serviceManager,因此获取这些service的方式比较固定:

/frameworks/base/core/java/android/app/ContextImpl.java

registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
294                public Object createService(ContextImpl ctx) {
295                    IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
296                    IAccountManager service = IAccountManager.Stub.asInterface(b);
297                    return new AccountManager(ctx, service);
298                }});

就是看看这个b是怎么转化成BinderProxy的 

/frameworks/base/core/java/android/os/ServiceManager.java

49    public static IBinder getService(String name) {
50        try {
51            IBinder service = sCache.get(name);
52            if (service != null) {
53                return service;
54            } else {
55                return getIServiceManager().getService(name);
56            }
57        } catch (RemoteException e) {
58            Log.e(TAG, "error in getService", e);
59        }
60        return null;
61    }

继续调用:

private static IServiceManager getIServiceManager() {
34        if (sServiceManager != null) {
35            return sServiceManager;
36        }
37
38        // Find the service manager
39        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
40        return sServiceManager;
41    }

那就看下:

/frameworks/base/core/java/android/os/ServiceManagerNative.java

static public IServiceManager asInterface(IBinder obj)
34    {
35        if (obj == null) {
36            return null;
37        }
38        IServiceManager in =
39            (IServiceManager)obj.queryLocalInterface(descriptor);
40        if (in != null) {
41            return in;
42        }
43
44        return new ServiceManagerProxy(obj);
45    }
46

关键点:这里和普通adil生成的asInterface没有区别,判断本地或者代理。所以区别点在上一步传入的obj,就是BinderInternal.getContextObject()

继续尾随:

/frameworks/base/core/java/com/android/internal/os/BinderInternal.java

public static final native IBinder getContextObject();

有货,进入jni去native了,binder的jni在

/frameworks/base/core/jni/android_util_Binder.cpp

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

先获取一个b,然后转化成java层的Binder,ok

/frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
90{
91    return getStrongProxyForHandle(0);
92}

继续,结果快出来了:

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
184{
185    sp<IBinder> result;
186
187    AutoMutex _l(mLock);
188
189    handle_entry* e = lookupHandleLocked(handle);
190
191    if (e != NULL) {
192        // We need to create a new BpBinder if there isn't currently one, OR we
193        // are unable to acquire a weak reference on this current one.  See comment
194        // in getWeakProxyForHandle() for more info about this.
195        IBinder* b = e->binder;
196        if (b == NULL || !e->refs->attemptIncWeak(this)) {
197            b = new BpBinder(handle);
198            e->binder = b;
199            if (b) e->refs = b->getWeakRefs();
200            result = b;
201        } else {
202            // This little bit of nastyness is to allow us to add a primary
203            // reference to the remote proxy when this team doesn't have one
204            // but another team is sending the handle to us.
205            result.force_set(b);
206            e->refs->decWeak(this);
207        }
208    }
209
210    return result;
211}

看注释也很清晰了,会new一个BpBinder或者持有已有BpBinder的弱索引,好了,在这里得到了BpBinder,往上回退两步,刚进jni的时候发现了,获得一个b,会转化成java的Binder,看下:

/frameworks/base/core/jni/android_util_Binder.cpp

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
556{
557    if (val == NULL) return NULL;
558
559    if (val->checkSubclass(&gBinderOffsets)) {
560        // One of our own!
561        jobject object = static_cast<JavaBBinder*>(val.get())->object();
562        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
563        return object;
564    }
565
566    // For the rest of the function we will hold this lock, to serialize
567    // looking/creation of Java proxies for native Binder proxies.
568    AutoMutex _l(mProxyLock);
569
570    // Someone else's...  do we know about it?
571    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
572    if (object != NULL) {
573        jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
574        if (res != NULL) {
575            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
576            return res;
577        }
578        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
579        android_atomic_dec(&gNumProxyRefs);
580        val->detachObject(&gBinderProxyOffsets);
581        env->DeleteGlobalRef(object);
582    }
583
584    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
585    if (object != NULL) {
586        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
587        // The proxy holds a reference to the native object.
588        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
589        val->incStrong(object);
590
591        // The native object needs to hold a weak reference back to the
592        // proxy, so we can retrieve the same proxy if it is still active.
593        jobject refObject = env->NewGlobalRef(
594                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
595        val->attachObject(&gBinderProxyOffsets, refObject,
596                jnienv_to_javavm(env), proxy_cleanup);
597
598        // Also remember the death recipients registered on this proxy
599        sp<DeathRecipientList> drl = new DeathRecipientList;
600        drl->incStrong((void*)javaObjectForIBinder);
601        env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
602
603        // Note that a new object reference has been created.
604        android_atomic_inc(&gNumProxyRefs);
605        incRefsCreated(env);
606    }
607
608    return object;
609}

这个函数有点长,看着就烦,分布看主要点,三个if

第一,own转化成JavaBBinder就是Binder

第二,else转化成BinderProxy

第三,小意外,new一个BinderProxy

 

再往前回顾:IServiceManager asInterface 返回的是new ServiceManagerProxy(obj),而其上一步调用的getService也是ServiceManagerProxy的getService

/frameworks/base/core/java/android/os/ServiceManagerNative.java

public IBinder getService(String name) throws RemoteException {
119        Parcel data = Parcel.obtain();
120        Parcel reply = Parcel.obtain();
121        data.writeInterfaceToken(IServiceManager.descriptor);
122        data.writeString(name);
123        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
124        IBinder binder = reply.readStrongBinder();
125        reply.recycle();
126        data.recycle();
127        return binder;
128    }

这里返回了BinderProxy

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值