当前位置 : 主页 > 手机开发 > android >

Android Framework如何实现Binder

来源:互联网 收集:自由互联 发布时间:2023-02-01
目录 Framework如何实现Binder ServiceManager 小结 Binder结构 Framework如何实现Binder 为了日常的使用framework层同样实现了一套binder的接口。可以肯定的是framework使用jni调用的是native的binder接口,
目录
  • Framework如何实现Binder
    • ServiceManager
    • 小结
  • Binder结构

    Framework如何实现Binder

    为了日常的使用framework层同样实现了一套binder的接口。可以肯定的是framework使用jni调用的是native的binder接口,在native层Binder结构通过BBinder,BpBinder和ServiceManager来实现。

    ServiceManager

    framework层的ServiceManager的路径在frameworks/base/core/java/android/os/ServiceManager.java。从ServiceManager最重要的两个功能addService和getService来看下framework层的实现。

        public static void addService(String name, IBinder service, boolean allowIsolated,
                int dumpPriority) {
            try {
                getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
            } catch (RemoteException e) {
                Log.e(TAG, "error in addService", e);
            }
        }
        private static IServiceManager getIServiceManager() {
            if (sServiceManager != null) {
                return sServiceManager;
            }
    ​
            // Find the service manager
            sServiceManager = ServiceManagerNative
                    .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
            return sServiceManager;
        }
    public final class ServiceManagerNative {
        private ServiceManagerNative() {}
    ​
        /**
         * Cast a Binder object into a service manager interface, generating
         * a proxy if needed.
         *
         * TODO: delete this method and have clients use
         *     IServiceManager.Stub.asInterface instead
         */
        @UnsupportedAppUsage
        public static IServiceManager asInterface(IBinder obj) {
            if (obj == null) {
                return null;
            }
            // ServiceManager is never local
            return new ServiceManagerProxy(obj);
        }
    }

    getIServiceManager()获取的实际是一个ServiceManagerProxy对象。构造函数的参数Binder.allowBlocking(BinderInternal.getContextObject())

    //frameworks/base/core/java/android/os/Binder.java 
    public static IBinder allowBlocking(IBinder binder) {//判断了下是不是本地binder设置了mWarnOnBlocking,就返回了,所以还是传入的binder
            try {
                if (binder instanceof BinderProxy) {
                    ((BinderProxy) binder).mWarnOnBlocking = false;
                } else if (binder != null && binder.getInterfaceDescriptor() != null
                        && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
                    Log.w(TAG, "Unable to allow blocking on interface " + binder);
                }
            } catch (RemoteException ignored) {
            }
            return binder;
        }
    //frameworks/base/core/java/com/android/internal/os/BinderInternal.java
     public static final native IBinder getContextObject();

    是个native方法

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

    回到了熟悉的native层,ProcessState::self()->getContextObject(NULL)获取了ServiceManager的代理Bpbinder(0),调用javaObjectForIBinder()封装成java对象返回。

    ​jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
    {
        if (val == NULL) return NULL;
    ​
        if (val->checkSubclass(&gBinderOffsets)) {//如果是一个JavaBBinder对象直接返回
            // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
            jobject object = static_cast<JavaBBinder*>(val.get())->object();
            LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
            return object;
        }
        BinderProxyNativeData* nativeData = new BinderProxyNativeData();//创建了一个BinderProxyNativeData对象并把传进来的binder设置给mObject
        nativeData->mOrgue = new DeathRecipientList;
        nativeData->mObject = val;
    ​
        jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
                gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());//调用了gBinderProxyOffsets.mGetInstance方法创建了一个binderproxy
        if (env->ExceptionCheck()) {
            // In the exception case, getInstance still took ownership of nativeData.
            return NULL;
        }
        BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
        if (actualNativeData == nativeData) {//
            // Created a new Proxy
            uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);//memory_order_relaxed类似volatile的功能
            uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
            if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
                // Multiple threads can get here, make sure only one of them gets to
                // update the warn counter.
                if (gProxiesWarned.compare_exchange_strong(numLastWarned,
                            numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
                    ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
                }
            }
        } else {
            delete nativeData;
        }
        return object;
    }

    gBinderProxyOffsets.mGetInstance这个方法的定义在frameworks/base/core/jni/android_util_Binder.cpp

        gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
                "(JJ)Landroid/os/BinderProxy;");//就是BinderProxy的getInstance方法     
    //frameworks/base/core/java/android/os/BinderProxy.java
        private static BinderProxy getInstance(long nativeData, long iBinder) {
            BinderProxy result;
            synchronized (sProxyMap) {
                try {
                    result = sProxyMap.get(iBinder);//查看这个iBinder有没有在缓存中
                    if (result != null) {
                        return result;
                    }
                    result = new BinderProxy(nativeData);
                } catch (Throwable e) {
                    // We're throwing an exception (probably OOME); don't drop nativeData.
                    NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
                            nativeData);
                    throw e;
                }
                NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
                // The registry now owns nativeData, even if registration threw an exception.
                sProxyMap.set(iBinder, result);
            }
            return result;
        }

    所以gBinderProxyOffsets.mGetInstance就是通过BinderProxyNativeData和BpBinder(0)拿到了BinderProxy对象。回到javaObjectForIBinder中获取到BinderProxy对象之后调用了getBPNativeData,这个方法获取了BinderProxy对象的BinderProxyNativeData地址通过这个地址和前面创建的nativeData地址判断mGetInstance获取的到的对象是新创建的还是缓存里面的。如果不是缓存里的话就更新维护BinderProxy的一些值。

    class ServiceManagerProxy implements IServiceManager {
        public ServiceManagerProxy(IBinder remote) {//remote就是BinderProxy
            mRemote = remote;
            mServiceManager = IServiceManager.Stub.asInterface(remote);
        }
        public IBinder asBinder() {
            return mRemote;
        }
        @UnsupportedAppUsage
        public IBinder getService(String name) throws RemoteException {
            // Same as checkService (old versions of servicemanager had both methods).
            return mServiceManager.checkService(name);
        }
        public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
                throws RemoteException {
            mServiceManager.addService(name, service, allowIsolated, dumpPriority);
        }
        @UnsupportedAppUsage
        private IBinder mRemote;
        private IServiceManager mServiceManager;
    }

    addService和getService都是通过mServiceManager变量来实现的。IServiceManager是一个aidl文件编译之后生成java代码。

    public static android.os.IServiceManager asInterface(android.os.IBinder obj)
    {
        if ((obj == null)) {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof android.os.IServiceManager))) {
            return ((android.os.IServiceManager) iin);
        }
        return new android.os.IServiceManager.Stub.Proxy(obj);
    }

    IServiceManager.Stub.asInterface返回的就是android.os.IServiceManager.Stub.Proxy类型看下getService调用。

    @Override public android.os.IBinder getService(java.lang.String name) throws android.os.RemoteException
    {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        android.os.IBinder _result;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeString(name);
            boolean _status = mRemote.transact(Stub.TRANSACTION_getService, _data, _reply, 0);
            _reply.readException();
            _result = _reply.readStrongBinder();
        }
        finally {
            _reply.recycle();
            _data.recycle();
        }
        return _result;
    }

    就是调用的传入的BinderProxy的transact方法:

     public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
     ........
                final boolean result = transactNative(code, data, reply, flags);//去除前面的异常处理和oneway判断之后,真正的调用就是这一行
    ​
                if (reply != null && !warnOnBlocking) {
                    reply.addFlags(Parcel.FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT);
                }
    ​
                return result;
        }

    这是一个jni方法,它的实现也在frameworks/base/core/jni/android_util_Binder.cpp

    ​static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
            jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
    {
        ................
        Parcel* data = parcelForJavaObject(env, dataObj);
        Parcel* reply = parcelForJavaObject(env, replyObj);
        IBinder* target = getBPNativeData(env, obj)->mObject.get();//拿到前面存储的BinderProxyNativeData
        //printf("Transact from Java code to %p sending: ", target); data->print();
        status_t err = target->transact(code, *data, reply, flags);//调用transact
        //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
    ..................
        return JNI_FALSE;
    }

    getBPNativeData前面已经分析过了就是拿到了BinderProxyNativeData,mObject就是前面初始化传入的Bpbinder(0),最后就调用到了的transact方法。到这里之后就是走的native层的binder调用了BpBinder->transact() ->IPCThreadState::self()->transact() ->IPCThreadState::writeTransactionData->IPCThreadState::waitForResponse->BinderCallback-> IPCThreadState::getAndExecuteCommand->IPCThreadState::executeCommand->BnServiceManager::onTransact

    小结

    framework层ServiceManager的实现原理就解析到这了,总结一下通过jni方法创建了ServiceManager的BinderProxy对象,层层封装成了ServiceManagerNative。后续的调用实际都是调用的native层的Bpbinder的方法。

    Binder结构

    现在分析了和native层ServiceManager对应的ServiceManagerNative,同时也找到了Bpbinder对应的BinderProxy,现在就剩下了BBbinder,在framework中就是Binder类,看下Binder的构造函数。

     public Binder(@Nullable String descriptor) {
            mObject = getNativeBBinderHolder();//创建了一个JavaBBinderHolder对象,返回了指向这个对象的指针mObject
            NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);//管理与Java对象有关的native内存。
    ​
            if (FIND_POTENTIAL_LEAKS) {
                final Class<? extends Binder> klass = getClass();
                if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                        (klass.getModifiers() & Modifier.STATIC) == 0) {
                    Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
                        klass.getCanonicalName());
                }
            }
            mDescriptor = descriptor;
        }

    getNativeBBinderHolder是个native方法,实现还是在frameworks/base/core/jni/android_util_Binder.cpp

    static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
    {
        JavaBBinderHolder* jbh = new JavaBBinderHolder();
        return (jlong) jbh;
    }

    到这里好像只是创建了一个JavaBBinderHolder和Binder对象组合了起来,没有看到BBinder。其实这里用了一个延迟初始化,当这个Binder对象需要作为本地Binder对象传递的时候会使用Parcel的writeStrongBinder来进行封装。它也是一个native方法,具体实现在frameworks/base/core/jni/android_os_Parcel.cpp

    static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
    {
        Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
        if (parcel != NULL) {
            const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
            if (err != NO_ERROR) {
                signalExceptionForError(env, clazz, err);
            }
        }
    }
    //frameworks/base/core/jni/android_util_Binder.cpp
    sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
    {
        if (obj == NULL) return NULL;
    ​
        // Instance of Binder?
        if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
            JavaBBinderHolder* jbh = (JavaBBinderHolder*)
                env->GetLongField(obj, gBinderOffsets.mObject);
            return jbh->get(env, obj);//如果是Binder对象调用JavaBBinderHolder的get方法。
        }
    ​
        // Instance of BinderProxy?
        if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
            return getBPNativeData(env, obj)->mObject;
        }
    ​
        ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
        return NULL;
    }

    关键就在JavaBBinderHolder的get方法了:

    //frameworks/base/core/jni/android_util_Binder.cpp  
    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
        {
            AutoMutex _l(mLock);
            sp<JavaBBinder> b = mBinder.promote();
            if (b == NULL) {
                b = new JavaBBinder(env, obj);//创建JavaBBinder对象
                if (mVintf) {
                    ::android::internal::Stability::markVintf(b.get());
                }
                if (mExtension != nullptr) {
                    b.get()->setExtension(mExtension);
                }
                mBinder = b;
                ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
                     b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
            }
    ​
            return b;
        }​
    class JavaBBinder : public BBinder
    {
    public:
        JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
            : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
        {
            ALOGV("Creating JavaBBinder %p\n", this);
            gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
            gcIfManyNewRefs(env);
        }
    ​
        bool    checkSubclass(const void* subclassID) const
        {
            return subclassID == &gBinderOffsets;
        }
    ​
        jobject object() const
        {
            return mObject;
        }

    JavaBBinder就是继承了BBinder对象,到这里Binder的Java对象和BBinder也关联了起来。而Binder结构的三个组成部分client(Binder),service(BinderProxy),ServiceManagert(ServiceManagerNative)都一一有了对应,具体通讯的功能都是通过jni对应到了native层的binder架构BBinder,BpBinder,ServiceManager来实现。

    到此这篇关于Android Framework如何实现Binder的文章就介绍到这了,更多相关Android 实现Binder内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    上一篇:Android自定义控件实现雷达图效果
    下一篇:没有了
    网友评论