binder机制在java层的使用

本文详细介绍了Android系统中Java层的Binder架构,包括其成员分析、初始化过程以及通过AMS如何工作。Java层的Binder架构是Native层的镜像,涉及到ibinder接口、binder类、binderproxy类以及初始化函数的注册。文章通过源码解析阐述了AMS如何注册到ServiceManager,以及服务端和客户端如何交互,揭示了Binder在Java层的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java层binder架构实际上也是基于c/s架构的,而且其在类的命名上也尽量与native层保持一致,因此可认为java层的binder架构是native层binder架构的一个镜像。

## 1 java层的binder架构成员分析 ##

- 系统定义了一个ibinder接口类及deathrecipient接口
- binder类和binderproxy实现了ibinder接口类。其中binder类作为服务端bn的代表,而binderproxy作为客户端bp的代表。
- binderinternal是一个仅供binder架构框架使用的类,内部类gcwatcher类,主要用来处理和binder相关的垃圾回收。
- java层同样提供了一个用于承载通信数据的parcel类。

## 2 Binder架构的初始化 ##
上面提到了java层Binder系统是Native层Binder系统的一个镜像,但是这个镜像终归还是依赖Native层Binder系统来展开工作,即镜像与Native层Binder关系密切,所以java层Binder正式工作之前就需要建立起这种关系。在Android系统中的java世界刚起来的时候,系统会提前注册一些jni函数,其中有一个函数专门负责搭建javaBinder和nativeBinder交互关系:

这个文件位于frameworks/base/core/jni/android_util_Binder.cpp:

    int register_android_os_Binder(JNIEnv* env)
    {
        //初始化Java Binder与Native层的关系
        if (int_register_android_os_Binder(env) < 0)
            return -1;
        //初始化Java BinderInternal与Native层的关系
           if (int_register_android_os_BinderInternal(env) < 0)
            return -1;
        //初始化Java BinderProxy与Native层的关系
        if (int_register_android_os_BinderProxy(env) < 0)
            return -1;
        ......
            return 0;
    }

Binder类的初始化:

    const char* const kBinderPathName = "android/os/Binder";

    static int int_register_android_os_Binder(JNIEnv* env)
    {
        jclass clazz = FindClassOrDie(env, kBinderPathName);

        gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
        gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");

        return RegisterMethodsOrDie(
            env, kBinderPathName,
            gBinderMethods, NELEM(gBinderMethods));
    }

BinderInternal类的初始化:

    const char* const kBinderInternalPathName = "com/android/    internal/os/BinderInternal";

    static int int_register_android_os_BinderInternal(JNIEnv* env)
    {
        jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

        gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env,     clazz, "forceBinderGc", "()V");

        return RegisterMethodsOrDie(
            env, kBinderInternalPathName,
            gBinderInternalMethods, NELEM(gBinderInternalMethods));
    }

BinderProxy类的初始化:

    const char* const kBinderProxyPathName = "android/os/BinderProxy";

    static int int_register_android_os_BinderProxy(JNIEnv* env)
    {
        jclass clazz = FindClassOrDie(env, "java/lang/Error");
        gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

        clazz = FindClassOrDie(env, kBinderProxyPathName);
        gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env,     clazz, "<init>", "()V");
        gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie    (env, clazz, "sendDeathNotice",
                "(Landroid/os/IBinder$DeathRecipient;)V");

        gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz,     "mObject", "J");
        gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz,     "mSelf", "Ljava/lang/ref/    WeakReference;");
        gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz,     "mOrgue", "J");

        clazz = FindClassOrDie(env, "java/lang/Class");
            gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

        return RegisterMethodsOrDie(
            env, kBinderProxyPathName,
            gBinderProxyMethods, NELEM(gBinderProxyMethods));
    }

至此,Java Binder几个重要成员的初始化已完成,在native代码中定义了几个全局静态对象,分别是gBinderOffsets、 gBinderInternalOffsets、 gBinderProxyOffsets。框架的初始化这项工作是必须的,因为它能节省每次使用时获取这些信息的时间,当Binder调用频繁时,这些时间累积起来还是不可小觑的。

## 3 通过AMS来揭示Java Binder的工作流程 ##

- AMS是如何将自己注册到ServiceManager中
- AMS是如何响应客户端的请求

### 3.1  AMS是如何将自己注册到ServiceManager中 ###

直接看代码吧,相信大家对这一块相当的熟悉了:

    framewroks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public void setSystemProcess() 
    {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
            ......
        }catch(){}

    }

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

    public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } 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(BinderInternal.getContextObject());
        return sServiceManager;
    }

重点来了,关键字Binder出现了,来看看BinderInternal.getContextObject()到底返回的是什么:

    frameworks/base/core/jni/android_util_Binder.cpp

    static jobject android_os_BinderInternal_getContextObject(JNIEnv*     env, jobject clazz)
    {
        //在上节我们讲解native层Binder时有提到过,它返回的是一个BpBinder对象,它的handle值是0
        sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
        return javaObjectForIBinder(env, b);
    }

相当于是:

    sp<IBinder> b = new BpBinder(0);    

接着调用javaObjectForIBinder把这个BpBinder对象转换为一个BinderProxy对象:

    jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
    {
        if (val == NULL) return NULL;
           ......

        //val对象类型是BpBinder    
        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对象,并将它注册到Natice BpBinder对象的ObjectManager中
        object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
        if (object != NULL) {
            ......

            //通过BinderProxy.mObject,把这个BpBinder对象和BinderProxy对象关联了起来
            env->SetLongField(object, gBinderProxyOffsets.mObject,     (jlong)val.get());
               ......

            val->attachObject(&gBinderProxyOffsets, refObject,
                    jnienv_to_javavm(env), proxy_cleanup);

            // Also remember the death recipients registered on this     proxy

            //保存了一个用户死亡通知的list
            sp<DeathRecipientList> drl = new DeathRecipientList;
            drl->incStrong((void*)javaObjectForIBinder);
            //将死亡通知list与BinderProxy对象关联起来
            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;
    }

最后BinderInternal.getContextObject()返回的就是一个BinderProxy对象,这个对象与native BpBinder关联,而BpBinder的通信目标就是ServiceManager。

回到ServiceManager.getIServiceManager中,从下面语句返回:

    sServiceManager = ServiceManagerNative.asInterface    (BinderInternal.getContextObject());

相当于是:

    sServiceManager = ServiceManagerNative.asInterface(new     BinderProxy());

接下来看看asInterface函数了:

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

    public abstract class ServiceManagerNative ......
    {
        ......
        static public IServiceManager asInterface(IBinder obj)
        {
            if (obj == null) {
                return null;
            }

            IServiceManager in =
                (IServiceManager)obj.queryLocalInterface(descriptor);
            if (in != null) {
                return in;
            }
            //这里obj是一个BinderProxy对象,以这个对象为参数创建一个ServiceManagerProxy对象
            return new ServiceManagerProxy(obj);
        }
        ......
    }

返回到ServiceManager.getIServiceManager中,从下面语句返回:
    
    sServiceManager = ServiceManagerNative.asInterface(new     BinderProxy());    

    相当于:

    sServiceManager = new ServiceManagerProxy(new BinderProxy());

再来看看addService函数:

    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        //writeStrongBinder是什么鬼,稍后来分析它
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        //mRemote实际上是BinderProxy对象,调用它的transact方法将封装好的请求数据发送出去
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

BinderProxy.transact函数具体实现也是在native中:
    
    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
    {
        ......
        
        //从java的parcel对象中得到作为参数的native的parcel对象
        Parcel* data = parcelForJavaObject(env, dataObj);
        if (data == NULL) {
            return JNI_FALSE;
        }

        //得到一个用于接收回复的Parcel对象
        Parcel* reply = parcelForJavaObject(env, replyObj);
        if (reply == NULL && replyObj != NULL) {
            return JNI_FALSE;
        }
    
        //从java的BinderProxy对象中得到之前创建好的BpBinder对象
        IBinder* target = (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
        if (target == NULL) {
            jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
            return JNI_FALSE;
        }
    
        ......
    
        //printf("Transact from Java code to %p sending: ", target); data->print();
        //通过BpBinder将请求发送给ServiceManager
        status_t err = target->transact(code, *data, reply, flags);
         ......

        return JNI_FALSE;
    }

看到上面的代码你会发现,Java层的Binder最终还是要借助native的Binder进行通信。到了这一步,相信大家应该有所印象了,是不是又走到了上一节MediaPlayerService的addService流程了。

上面有提到过data.writeStrongBinder(service),下面将会作为解释,先请看下ams的继承关系:

    public class ActivityManagerService extends ActivityManagerNative

    public abstract class ActivityManagerNative extends Binder implements IActivityManager

    Binder.java
    public Binder() {
        init();
    }

Binder的构造函数会调用native的init函数,来看看它的实现:

    static void android_os_Binder_init(JNIEnv* env, jobject obj)
    {
        //创建一个JavaBBinderHolder对象
        JavaBBinderHolder* jbh = new JavaBBinderHolder();
        if (jbh == NULL) {
            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
            return;
        }
        ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
        jbh->incStrong((void*)android_os_Binder_init);
        //将上面的JavaBinderHolder对象保存到java Binder对象的mObject成员中
        env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
    }

来看看JavaBBinderHolder又是什么鬼:
    
    class JavaBBinderHolder : public RefBase
    {
    public:
        sp<JavaBBinder> get(JNIEnv* env, jobject obj)
        {
            AutoMutex _l(mLock);
            sp<JavaBBinder> b = mBinder.promote();
            if (b == NULL) {
                //创建一个JavaBBinder。obj是java层的Binder对象
                b = new JavaBBinder(env, obj);
                mBinder = b;
                ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
                     b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
            }
    
            return b;
        }
        ......
    };

好了,回归到data.writeStrongBinder(service),它是一个native函数:

    frameworks/base/core/jni/android_util_Binder.cpp

    //clazz是java语言实现的parcel对象,object是java语言实现的Binder对象
    static void android_os_Parcel_writeStrongBinder(JNIEnv* env,     jobject clazz, jobject object)
    {
        Parcel* parcel = parcelForJavaObject(env, clazz);
        if (parcel != NULL) {
            const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
            if (err != NO_ERROR) {
                jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
            }
        }
    }

    sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
    {
        if (obj == NULL) return NULL;
        //如果java的obj是Binder类,则首先获得JavaBBinderHolder对象,然后调用它的get函数返回一个javaBBinder
        if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
            JavaBBinderHolder* jbh = (JavaBBinderHolder*)
                env->GetLongField(obj, gBinderOffsets.mObject);
            return jbh != NULL ? jbh->get(env, obj) : NULL;
        }
    
        //如果obj是BinderProxy对象,则返回BpBinder对象
        if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
            return (IBinder*)
                env->GetLongField(obj, gBinderProxyOffsets.mObject);
        }
    
        ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
        return NULL;
    }
    
好了,让我们再回顾一下addService的过程,最终将通过BpBinder:transat()函数进入到binder驱动程序,然后Binder驱动程序唤醒ServiceManager响应这个ADD_SERVICE_TRANSACTION请求。需要注意的是,这里的data包含了一个JavaBBinderHolder类型的Binder实体对象,它代表着我们的AMS。ServiceManager收到这个ADD_SERVICE_TRANSACTION请求时,就会把这个Binder实体纳入到自己内部进行管理。

### 3.2 AMS响应请求 ###

当ams收到请求时,系统会调用JavaBBinder的transact函数:

    frameworks/base/core/jni/android_util_Binder.cpp

    virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {
        ......

        IPCThreadState* thread_state = IPCThreadState::self();
   
        //调用Java Binder的execTransact函数
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

         ......

        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
    }

就本例而言,上面代码中的mObject就是ams,现在调用它的exectransact()方法,该方法在Binder类中实现,如下:

    public class Binder implements IBinder
    {
        private boolean execTransact(int code, int dataObj, int     replyObj, int flags) {
            Parcel data = Parcel.obtain(dataObj);
            Parcel reply = Parcel.obtain(replyObj);

            boolean res;
            try {
                //调用onTransact函数,子类可以重新实现这个函数以完成业务功能
                res = onTransact(code, data, reply, flags);
            } catch { ...... }

            reply.recycle();
            data.recycle();
            return res;
        }
    }

ActivityManagerNative类也实现了onTransact函数,如下:

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException 
    {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
            //再由ams实现业务函数startActivity
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }
        ......
    }

到此,ams响应客户端的请求就大概分析完了。

## 4 学以致用 ##
经过以上的讲解,我们明白在Java Binder的结构中,Bp端可以通过BinderProxy的transact()方法与Bn端发送请求,而Bn端通过继承Binder类重写onTransact()接受并处理Bp端的请求。下面就用一个简单的demo来实现基于Binder机制的进程间通信:

1 定义接口

    package com.example.multiprocessdemo;

    interface IHelloService
    {
        void setVal(int val);
        int getVal();
    }

2 利用as中的aidl工具将其解析为一个实现了Bn端及Bp端进行通信的Java源代码 

    package com.example.multiprocessdemo;
    // Declare any non-default types here with import statements
    
    //1.首先,IHelloService.aidl被解析为一个Java接口IHelloService
    这个接口定义aidl中所定义的接口setVal()及getVal()
    public interface IHelloService extends android.os.IInterface
    {
        /** Local-side IPC implementation stub class. */
        //2.生成了一个继承自IHelloService接口的抽象类IHelloService.Stub。这个抽象类实现了Bn端通过onTransact()方法来接收来自Bp端的请求代码。
        public static abstract class Stub extends android.os.Binder implements com.example.multiprocessdemo.IHelloService
        {
        private static final java.lang.String DESCRIPTOR = "com.example.multiprocessdemo.IHelloService";
        /** Construct the stub at attach it to the interface. */
        public Stub()
        {
        this.attachInterface(this, DESCRIPTOR);
        }
        /**
         * Cast an IBinder object into an com.example.multiprocessdemo.IHelloService interface,
         * generating a proxy if needed.
         */
        public static com.example.multiprocessdemo.IHelloService asInterface(android.os.IBinder obj)
        {
        if ((obj==null)) {
        return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin!=null)&&(iin instanceof com.example.multiprocessdemo.IHelloService))) {
        return ((com.example.multiprocessdemo.IHelloService)iin);
        }
        return new com.example.multiprocessdemo.IHelloService.Stub.Proxy(obj);
        }
        @Override public android.os.IBinder asBinder()
        {
        return this;
        }
        @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
        {
        java.lang.String descriptor = DESCRIPTOR;
        switch (code)
        {
        case INTERFACE_TRANSACTION:
        {
        reply.writeString(descriptor);
        return true;
        }
        case TRANSACTION_setVal:
        {
        data.enforceInterface(descriptor);
        int _arg0;
        _arg0 = data.readInt();
        this.setVal(_arg0);
        reply.writeNoException();
        return true;
        }
        case TRANSACTION_getVal:
        {
        data.enforceInterface(descriptor);
        int _result = this.getVal();
        reply.writeNoException();
        reply.writeInt(_result);
        return true;
        }
        default:
        {
        return super.onTransact(code, data, reply, flags);
        }
        }
        }
        //还生成了一个实现IHelloService接口的类Proxy,它是Bp的实现
        private static class Proxy implements com.example.multiprocessdemo.IHelloService
        {
        private android.os.IBinder mRemote;
        Proxy(android.os.IBinder remote)
        {
        mRemote = remote;
        }
        @Override public android.os.IBinder asBinder()
        {
        return mRemote;
        }
        public java.lang.String getInterfaceDescriptor()
        {
        return DESCRIPTOR;
        }
        /**
             * Demonstrates some basic types that you can use as parameters
             * and return values in AIDL.
             */
        @Override public void setVal(int val) throws android.os.RemoteException
        {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
        _data.writeInterfaceToken(DESCRIPTOR);
        _data.writeInt(val);
        mRemote.transact(Stub.TRANSACTION_setVal, _data, _reply, 0);
        _reply.readException();
        }
        finally {
        _reply.recycle();
        _data.recycle();
        }
        }
        @Override public int getVal() throws android.os.RemoteException
        {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        int _result;
        try {
        _data.writeInterfaceToken(DESCRIPTOR);
        mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
        _reply.readException();
        _result = _reply.readInt();
        }
        finally {
        _reply.recycle();
        _data.recycle();
        }
        return _result;
        }
        }
        static final int TRANSACTION_setVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_getVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        }
        /**
             * Demonstrates some basic types that you can use as parameters
             * and return values in AIDL.
             */
        public void setVal(int val) throws android.os.RemoteException;
        public int getVal() throws android.os.RemoteException;
    }

3 实现一个Bn端

    package com.example.multiprocessdemo;

    import android.os.RemoteException;

    public class HelloServer extends IHelloService.Stub 
    {
           @Override
        public void setVal(int val) throws RemoteException { 
        //.......       
        }
    
        @Override
        public int getVal() throws RemoteException {
            return 0;
           }
    }

就这样,每一个HelloServer的实例,都具有了作为Bn端的能力。典型的做法就是将HelloServer的实例通过ServiceManager.addService()方法将其注册为一个系统服务。或者在一个Android标准的service的onBind()方法中将其作为返回值使之可以被其他进程访问。另外,也可以通过    Binder调用将其传递给另外一个进程,使之成为一个跨进程的回调对象。我这里以在一个Android标准的service的onBind()方法中将其作为返回值为例演示下:

    package com.example.multiprocessdemo;

    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;
    
    public class HelloService extends Service {

        private int i = 0;
    
        private final IHelloService.Stub mBinder = new IHelloService.Stub() {
            @Override
            public void setVal(int val) throws RemoteException {
                i = val;
                Log.d("zhangjx","setVal i ==  " + i);
            }
    
            @Override
            public int getVal() throws RemoteException {
                Log.d("zhangjx","getVal ");
                return i;
            }
        };
    
        @Override
        public IBinder onBind(Intent intent) {
            Log.d("zhangjx","onBind ");
            return mBinder;
        }
    }

4 Bp端的使用

那么Bp端将如何使用IHelloService.Proxy呢?一般在Bp端所在的进程中,一旦获取了IHelloService的BinderProxy,就可以通过如下方式获得一个IHelloService.Proxy:

    //方式一:其中BinderProxy是通过ServiceManager.getService()获取的
    IHelloService helloService = IHelloService.Stub.asInterface(BinderProxy);

    //方式二:通过ServiceConnection的onServiceConnected()获取
    private IHelloService helloService = null;

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("zhangjx","onServiceConnected");
            helloService = IHelloService.Stub.asInterface(service);
            try {
                helloService.setVal(1111);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("zhangjx","onServiceDisconnected");
        }
    };
    
再来看看这个demo的manifest:
    
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.multiprocessdemo">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".HelloActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service android:name=".HelloService"
            android:process=":helloservice">
            <intent-filter>
                <action android:name="com.example.multiprocessdemo.hello" />
            </intent-filter>
        </service>

    </application>

    </manifest>
    
以上一个简单的demo就展示了简单的跨进程通信,到这里,相信大家都Binder的理解应该更上一层楼了吧!

## Java层Binder架构总结 ##

- 对于代表客户端的BinderProxy来说,Java层的BinderProxy在Native层对应已给BpBinder对象。凡是从Java层发出的请求,首先从Java层的BinderProxy传递到Native层的BpBinder,再由BpBinder将请求发送到Binder驱动。

- 对于代表服务端的Service来说,Java层的Binder在Native层有一个JavaBBinder对象。所有Java层的Binder在Native层都有对应的JavaBBinder,它负责把来自客户端的请求从Native层传递到Java层。

- 系统中依然只有一个Native的ServiceManager。

至此,Java层的Binder架构已介绍完毕,从前面的分析可以看出,Java层的Binder非常依赖Native层的Binder。

 

  
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值