【安卓源码】Binder机制5 -- Java层Framework Binder机制和 AIDL

news2025/4/7 20:20:46

  • 图中红色代表整个framework层 binder架构相关组件;
    • Binder类代表Server端,BinderProxy类代码Client端;
  • 图中蓝色代表Native层Binder架构相关组件;
  • 上层framework层的Binder逻辑是建立在Native层架构基础之上的,核心逻辑都是交予Native层方法来处理。
  • framework层的ServiceManager类与Native层的功能并不完全对应,framework层的ServiceManager类的实现最终是通过BinderProxy传递给Native层来完成的

一. 注册 jni ,java 可以调用 native 层代码

因为 应用进程均是 zygote fork 出来的子进程,会复制父进程的内存

/frameworks/base/cmds/app_process/app_main.cpp

173  int main(int argc, char* const argv[])
174  {
175      if (!LOG_NDEBUG) {

。。。。

// AppRuntime  实例
185      AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// 看是启动 zygote 、SystemServer 还是普通 application
264      while (i < argc) {
265          const char* arg = argv[i++];
266          if (strcmp(arg, "--zygote") == 0) {
267              zygote = true;
268              niceName = ZYGOTE_NICE_NAME;
269          } else if (strcmp(arg, "--start-system-server") == 0) {
270              startSystemServer = true;
271          } else if (strcmp(arg, "--application") == 0) {
272              application = true;
273          } else if (strncmp(arg, "--nice-name=", 12) == 0) {
274              niceName.setTo(arg + 12);
275          } else if (strncmp(arg, "--", 2) != 0) {
276              className.setTo(arg);
277              break;
278          } else {
279              --i;
280              break;
281          }
282      }
283  

。。。。。。。
335      if (zygote) {
336          runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
337      } else if (className) {
338          runtime.start("com.android.internal.os.RuntimeInit", args, zygote);

AppRuntime start("com.android.internal.os.RuntimeInit", args, zygote) 启动一个普通应用或者zygote,都会注册jni

// AppRuntime 继承了 AndroidRuntime

34  class AppRuntime : public AndroidRuntime
35  {

/frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
            className != NULL ? className : "(unknown)", getuid());

    static const String8 startSystemServer("start-system-server");

。。。。。

// 开启虚拟机
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;

// VM 
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */

// 注册安卓 jni,让java层可以调用 cpp 代码
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

startReg 函数

/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    ATRACE_NAME("RegisterAndroidNatives");

    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    env->PushLocalFrame(200);


// 这里去注册 jni 
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }

register_jni_procs(gRegJNI, NELEM(gRegJNI), env)

看下:gRegJNI

// RegJNIRec 是个结构体,里面是调用的函数,使用 mProc 表示
// 所以 gRegJNI 是个结构体数组
static const RegJNIRec gRegJNI[] = {
    REG_JNI(register_com_android_internal_os_RuntimeInit),
    REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
    REG_JNI(register_android_os_SystemClock),
    REG_JNI(register_android_util_EventLog),

// 这里注册了 log 机制
    REG_JNI(register_android_util_Log),
    REG_JNI(register_android_util_MemoryIntArray),
    REG_JNI(register_android_util_PathParser),

// 这里就去注册了binder 机制的一些函数
    REG_JNI(register_android_os_Binder),
    REG_JNI(register_android_os_Parcel),

=========
#ifdef NDEBUG

// REG_JNI 宏定义了函数的名字
    #define REG_JNI(name)      { name }
    struct RegJNIRec {
        int (*mProc)(JNIEnv*);
    };

所以 gRegJNI 是个结构体数组。NELEM(gRegJNI) 是计算该数组的大小 size

接着调用 register_jni_procs 函数:

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    for (size_t i = 0; i < count; i++) {

// 遍历所有的结构体,调用函数 mProc
        if (array[i].mProc(env) < 0) {
#ifndef NDEBUG
            ALOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
            return -1;
        }
    }
    return 0;
}

这里主要关注 register_android_os_Binder 函数

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

int register_android_os_Binder(JNIEnv* env)
{
    if (int_register_android_os_Binder(env) < 0)
        return -1;
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;

// 主要看下 int_register_android_os_BinderProxy 函数
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;

    jclass clazz = FindClassOrDie(env, "android/util/Log");
    gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");

    clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
    gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
                                                                 "(Ljava/io/FileDescriptor;)V");

主要看下 int_register_android_os_BinderProxy 函数

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

// const char* const kBinderProxyPathName = "android/os/BinderProxy";
// 获取 BinderProxy 类
    clazz = FindClassOrDie(env, kBinderProxyPathName);

// 设置全局的 mClass 为:BinderProxy
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

// BinderProxy 的静态方法 getInstance
    gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
            "(JJ)Landroid/os/BinderProxy;");

// BinderProxy 的静态方法 sendDeathNotice
    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
            "(Landroid/os/IBinder$DeathRecipient;)V");

// 设置变量 mNativeData
    gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");

    clazz = FindClassOrDie(env, "java/lang/Class");

// getName 方法
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

//RegisterMethodsOrDie 方法
    return RegisterMethodsOrDie(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}


======
// binderproxy_offsets_t 结构体为如下:
static struct binderproxy_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mGetInstance;
    jmethodID mSendDeathNotice;

    // Object state.
    jfieldID mNativeData;  // Field holds native pointer to BinderProxyNativeData.
} gBinderProxyOffsets;

RegisterMethodsOrDie 方法

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

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

// gBinderProxyMethods 为:

static const JNINativeMethod gBinderProxyMethods[] = {
     /* name, signature, funcPtr */
    {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
    {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
    {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
    {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
    {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
    {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
    {"getNativeFinalizer",  "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
};

// NELEM(gBinderProxyMethods) 为数组大小:
sizeof (gBinderProxyMethods) / sizeof(gBinderProxyMethods[0])

相当于将 java 层的方法,如gBinderProxyMethods ,映射到 cpp 中代码:android_os_BinderProxy_pingBinder

二. java 层 getIServiceManager 获取servicemanager

以设置 TelephonyRegistry 为例子

/frameworks/base/services/java/com/android/server/SystemServer.java

            telephonyRegistry = new TelephonyRegistry(context);
            ServiceManager.addService("telephony.registry", telephonyRegistry);

TelephonyRegistry 是 ITelephonyRegistry.Stub ,Stub 接口,是服务端的实现。在system 进程创建这个对象,则是运行在系统进程中。

99  public class TelephonyRegistry extends ITelephonyRegistry.Stub {
100      private static final String TAG = "TelephonyRegistry";

ServiceManager.addService("telephony.registry", telephonyRegistry)

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

    @UnsupportedAppUsage
    public static void addService(String name, IBinder service) {
        addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
    }

======
    @UnsupportedAppUsage
    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;
    }

获取 servicemanager 对象的实现为:

ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()))

1)先看下  BinderInternal.getContextObject() 的返回值

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

    @UnsupportedAppUsage
    public static final native IBinder getContextObject();

直接调用 native 层的代码:

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

static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },

// 下列有 2 个方法:joinThreadPool、setMaxThreads, 类似于 IPCThreadState 的方法
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },

android_os_BinderInternal_getContextObject 

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{

// 1-1)先获取 IBinder 对象
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);

// 1-2)将 IBinder 对象转换为 java 对象
    return javaObjectForIBinder(env, b);
}

1-1)先获取 IBinder 对象

ProcessState::self()->getContextObject(NULL)

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

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

======
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {

        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {

// servicemanager 的handle 是 0
            if (handle == 0) {

                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                if (status == DEAD_OBJECT)
                   return nullptr;
            }

// 创建 BpBinder 对象,handler =0
            b = BpBinder::create(handle);

// handle_entry缓存这个 binder
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {

            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

创建 BpBinder 对象,new BpBinder(0)

1-2)将 IBinder 对象转换为 java 对象

javaObjectForIBinder(env, b)

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

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

    if (val->checkSubclass(&gBinderOffsets)) {
        // 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();
    nativeData->mOrgue = new DeathRecipientList;
    nativeData->mObject = val;

// 调用 BinderProxy 的 getInstance 方法
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    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);
        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 = 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);
                if (result != null) {
                    return result;
                }

// 创建 BinderProxy 对象, nativeData 为BinderProxyNativeData
                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;
    }

创建 BinderProxy 对象, nativeData 为BinderProxyNativeData

综上:BinderInternal.getContextObject() 的返回值为:BinderProxy(BinderProxyNativeData())

2)Binder.allowBlocking(BinderProxy(BinderProxyNativeData())) 的返回值

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

    public static IBinder allowBlocking(IBinder binder) {
        try {

// 如果是 BinderProxy 实例,则设置 mWarnOnBlocking 为false
            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;
    }

返回的还是:BinderProxy(BinderProxyNativeData())

3)ServiceManagerNative.asInterface(BinderProxy(BinderProxyNativeData())) 的返回值

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

public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
    /**
     * Cast a Binder object into a service manager interface, generating
     * a proxy if needed.
     */
    @UnsupportedAppUsage
    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }

// 通过 BinderProxy 来查询本地的接口,如果有值,则直接返回
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

// 调用远端服务器端的接口
        return new ServiceManagerProxy(obj);
    }

====
// 返回为 null
     * Retrieve a local interface - always null in case of a proxy
     */
    public IInterface queryLocalInterface(String descriptor) {
        return null;
    }

创建对象 ServiceManagerProxy(obj)

a 12有所改动:

 */
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) {

// 这里如果是 binder 为 null,则直接返回空
        if (obj == null) {
            return null;
        }

        // ServiceManager is never local
        return new ServiceManagerProxy(obj);
    }
}

三. java 层 addService  和 getService 流程

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

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {

// 传入的 remote 为 BinderProxy
        mRemote = remote;
    }

    public IBinder asBinder() {
        return mRemote;
    }

=======
    @UnsupportedAppUsage
    public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);

// 3-1)调用 remote 的 transact方法
// addService 没有返回值,所以只看 transact 方法即可
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);

// 3-2)返回的 reply调用 readStrongBinder 方法
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

=========
    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        data.writeInt(dumpPriority);

// ADD_SERVICE_TRANSACTION
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

3-1)调用 remote 的 transact方法

调用 remote ==BinderProxy 的 transact方法

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

    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");

// mWarnOnBlocking 设置为 false 了
        if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
            mWarnOnBlocking = false;
            Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
                    new Throwable());
        }

        final boolean tracingEnabled = Binder.isTracingEnabled();

        final Binder.ProxyTransactListener transactListener = sTransactListener;
        Object session = null;

。。

        }

        try {

// 调用native 层的方法transactNative
            return transactNative(code, data, reply, flags);

=========
    public native boolean transactNative(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;

调用native 层的方法 transactNative

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

static const JNINativeMethod gBinderProxyMethods[] = {
     /* name, signature, funcPtr */
,,,
    {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},

=======

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
    if (dataObj == NULL) {
        jniThrowNullPointerException(env, NULL);
        return JNI_FALSE;
    }

    Parcel* data = parcelForJavaObject(env, dataObj);
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj);
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }

// 获取到 target 对象
// 在 nativeData->mObject = val; 有设置 mObject 为BpBinder
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }

    bool time_binder_calls;
    int64_t start_millis;

// 调用 target 的 transact 方法
// target 对象为 BpBinder 对象 
    status_t err = target->transact(code, *data, reply, flags);

// 判断返回的值是否有误
    if (err == NO_ERROR) {
        return JNI_TRUE;
    } else if (err == UNKNOWN_TRANSACTION) {
        return JNI_FALSE;
    }

// 如果有错,则通知上层
    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
    return JNI_FALSE;
}

target 对象为 BpBinder 对象 ,调用 target 的 transact 方法

/frameworks/native/libs/binder/BpBinder.cpp

// NOLINTNEXTLINE(google-default-arguments)
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

上述的流程就与前面分析的binder addservice 的流程是一样了

3-2)返回的 reply调用 readStrongBinder 方法

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

    public final IBinder readStrongBinder() {
        return nativeReadStrongBinder(mNativePtr);
    }

调用 native 层的方法:nativeReadStrongBinder

/frameworks/base/core/jni/android_os_Parcel.cpp

    {"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},

======
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {

// 调用方法:javaObjectForIBinder,参数是 parcel->readStrongBinder() 其实还是 cpp 层的代码
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}

调用方法:javaObjectForIBinder,参数是 parcel->readStrongBinder() 其实还是 cpp 层的代码,

由前面的分析可以知道:parcel->readStrongBinder() 为:new BpBinder(handle)

sp<IBinder> Parcel::readStrongBinder() const
{
    sp<IBinder> val;
 
    readNullableStrongBinder(&val);
    return val;
}
 
===========
status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
{
    return unflatten_binder(ProcessState::self(), *this, val);
}
 
=========
status_t unflatten_binder(const sp<ProcessState>& proc,
    const Parcel& in, sp<IBinder>* out)
{
    const flat_binder_object* flat = in.readObject(false);
 
    if (flat) {
        switch (flat->hdr.type) {
            case BINDER_TYPE_BINDER:
 
// 当请求服务的进程与服务属于同一进程。则直接调用BBinder 对象即可
                *out = reinterpret_cast<IBinder*>(flat->cookie);
                return finish_unflatten_binder(nullptr, *flat, in);
 
// 当请求服务的进程与服务不是在同一进程的话
// 返回的值是 BINDER_TYPE_HANDLE,flat->handle 是个数值
            case BINDER_TYPE_HANDLE:
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast<BpBinder*>(out->get()), *flat, in);
        }
    }
    return BAD_TYPE;
}

return javaObjectForIBinder(env, parcel->readStrongBinder());

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

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

    if (val->checkSubclass(&gBinderOffsets)) {
        // 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();
    nativeData->mOrgue = new DeathRecipientList;

// 设置 nativeData 的 mObject 为:BpBinder
    nativeData->mObject = val;

// 创建 BinderProxy 对象
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());

。。。。

    return object;
}

javaObjectForIBinder将native层BpBinder对象转换为Java层BinderProxy对象。 也就是说通过getService()最终获取了指向目标Binder服务端的代理对象BinderProxy。

1. ServiceManager.addService("telephony.registry", telephonyRegistry) 时,是在服务端进程进行的。servicemanager 进程会在 binder 驱动中缓存一个handle 句柄,与当前服务端映射。

2. getService 时,与 servicemanager 进程交互,获取到handle 句柄,【是相同进程的话,则直接是对象】===> BpBinde(handle)

3. 调用服务端方法,传下去的handle 找到目标服务器端进程,然后就可以调用服务端的方法了。

四. proxy 客户端与 Stub 服务端交互--AIDL 机制

1)aidl 自动生成的代码文件

package com.binderdemo;

public interface IRemoteService extends android.os.IInterface {

// ================ 静态的 Stub 类,是服务端的类 ================
// 服务端需要继承实现

    public static abstract class Stub extends android.os.Binder implements com.binderdemo.IRemoteService {

        private static final java.lang.String DESCRIPTOR = "com.binderdemo.IRemoteService";

        /**
         * Stub构造函数
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

// ================ 客户端调用的接口:asInterface ================
// IRemoteService.Stub.Proxy(obj)
// 1. obj 可以通过 ServiceManager.getService("XX") 获取
// 2. obj 也可以通过 onServiceConnected ,system进程回调给用户进程获取

        public static com.binderdemo.IRemoteService asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.binderdemo.IRemoteService))) {
                return ((com.binderdemo.IRemoteService) iin);
            }
            return new com.binderdemo.IRemoteService.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 {
            switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(DESCRIPTOR);
                    return true;
                }
                case TRANSACTION_getPid: {
                    data.enforceInterface(DESCRIPTOR);
                    int _result = this.getPid();
                    reply.writeNoException();
                    reply.writeInt(_result);
                    return true;
                }
                case TRANSACTION_getMyData: {
                    data.enforceInterface(DESCRIPTOR);
                    com.binderdemo.MyData _result = this.getMyData();
                    reply.writeNoException();
                    if ((_result != null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    } else {
                        reply.writeInt(0);
                    }
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

// ================ 静态的 Proxy 类,是客户端调用的类 ================
        private static class Proxy implements com.binderdemo.IRemoteService {
            private android.os.IBinder mRemote;

            /**
             * Proxy构造函数
             */
            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            @Override
            public int getPid() 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_getPid, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }

            @Override
            public com.binderdemo.MyData getMyData() throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                com.binderdemo.MyData _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_getMyData, _data, _reply, 0);
                    _reply.readException();
                    if ((0 != _reply.readInt())) {
                        _result = com.binderdemo.MyData.CREATOR.createFromParcel(_reply);
                    } else {
                        _result = null;
                    }
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        static final int TRANSACTION_getPid = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_getMyData = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }

    public int getPid() throws android.os.RemoteException;

    public com.binderdemo.MyData getMyData() throws android.os.RemoteException;
}

使用的方法,客户端和服务器端

  • 客户端
    private void bindRemoteService(){
        Log.i(TAG, "[ClientActivity] bindRemoteService");
        Intent intent = new Intent(ClientActivity.this, RemoteService.class);
        intent.setAction(IRemoteService.class.getName());
// 去绑定服务
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

====回调====
    private ServiceConnection mConnection = new ServiceConnection() {

// system 系统进程去回调
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

// 设置 service
            mRemoteService = IRemoteService.Stub.asInterface(service);
            String pidInfo = null;
            try {
                MyData myData = mRemoteService.getMyData();
                pidInfo = "pid="+ mRemoteService.getPid() +
                        ", data1 = "+ myData.getData1() +
                        ", data2="+ myData.getData2();

  • 服务器端
public class RemoteService extends Service {
    private static final String TAG = "BinderSimple";

    MyData mMyData;

// 返回给客户端的对象
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG,"[RemoteService] onBind");
        return mBinder;
    }


// 实现服务端的方法
    /** * 实现IRemoteService.aidl中定义的方法 */
    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {

        @Override
        public int getPid() throws RemoteException {
            Log.i(TAG,"[RemoteService] getPid()="+android.os.Process.myPid());
            return android.os.Process.myPid();
        }

        @Override
        public MyData getMyData() throws RemoteException {
            Log.i(TAG,"[RemoteService] getMyData() "+ mMyData.toString());
            return mMyData;
        }

        /**此处可用于权限拦截**/
        @Override
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            return super.onTransact(code, data, reply, flags);
        }
    };

2). bindService 回调 ServiceConnection的 onServiceConnected 方法

bindService 会走到如下流程去绑定服务:

/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

    int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String instanceName, String callingPackage, final int userId)
            throws TransactionTooLargeException {

。。。。。。
// 赋值给 ServiceRecord 对象
        ServiceLookupResult res =
            retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true,
                    callerFg, isBindExternal, allowInstant);

        ServiceRecord s = res.record;

========创建 ServiceRecord 对象========
                    r = new ServiceRecord(mAm, className, name, definingPackageName,
                            definingUid, filter, sInfo, callingFromFg, res);
                    res.setService(r);

=-==========
requestServiceBindingsLocked --> requestServiceBindingLocked

requestServiceBindingLocked

    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
        if (r.app == null || r.app.getThread() == null) {
            // If service is not currently running, can't yet bind.
            return false;
        }
        if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested
                + " rebind=" + rebind);
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind",
                        OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);

// r.app.getThread() 是 IApplicationThread ,又回到了应用进程
                r.app.getThread().scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.mState.getReportedProcState());
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;

在应用进程的主线程操作

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

        public final void scheduleBindService(IBinder token, Intent intent,
                boolean rebind, int processState) {
            updateProcessState(processState, false);
            BindServiceData s = new BindServiceData();
            s.token = token;
            s.intent = intent;
            s.rebind = rebind;

            if (DEBUG_SERVICE)
                Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
                        + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
            sendMessage(H.BIND_SERVICE, s);
        }

===============
    private void handleBindService(BindServiceData data) {
        CreateServiceData createData = mServicesData.get(data.token);

// 1)获取到 service 对象
        Service s = mServices.get(data.token);
        if (DEBUG_SERVICE)
            Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info),
                        s.getAttributionSource());
                try {
                    if (!data.rebind) {

// 2)调用 RemoteService 的 onBind 方法
                        IBinder binder = s.onBind(data.intent);

/// 3)将返回的服务器的binder 对象传给客户端
                        ActivityManager.getService().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to bind to service " + s
                            + " with " + data.intent + ": " + e.toString(), e);
                }
            }
        }
    }

=====1)获取到 service 对象 是通过反射来获取到对象 =====
    private void handleCreateService(CreateServiceData data) {
。。。
// 反射创建 RemoteService 对象
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
。。。。。。。
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            service.onCreate();
            mServicesData.put(data.token, data);
            mServices.put(data.token, service);

// 2)调用服务器端的 RemoteService 的 onBind 返回  new IRemoteService.Stub 对象
                        IBinder binder = s.onBind(data.intent);

当该服务被绑定的时候,Binder 驱动会为根据该服务所在的进程决定 是返回本地对象还是代理对象给客户端。

  • 当 Service 与 客户端位于同一个进程当中的时候,onServiceConnected 返回 Binder 本地对象——即 mBinder 对象给客户端;
  • 当 Service 运行在不同进程中的时候,返回的是 BinderProxy 对象。
public class RemoteService extends Service {
    private static final String TAG = "BinderSimple";

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG,"[RemoteService] onBind");
        return mBinder;
    }


    /** * 实现IRemoteService.aidl中定义的方法 */
    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {

 调用 Stub 的构造方法

public interface IRemoteService extends android.os.IInterface {

// Stub 继承了 Binder 对象
    public static abstract class Stub extends android.os.Binder implements com.binderdemo.IRemoteService {
        private static final java.lang.String DESCRIPTOR = "com.binderdemo.IRemoteService";

        /**
         * Stub构造函数
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

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

    public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
        mOwner = owner;
        mDescriptor = descriptor;
    }

// 查询远端对象
    public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
        if (mDescriptor != null && mDescriptor.equals(descriptor)) {
            return mOwner;
        }
        return null;
    }

在不同进程时候,BinderProxy 返回时空

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

    public IInterface queryLocalInterface(String descriptor) {
        return null;
    }

=========猜测不同进程返回的是 BinderProxy =========

调用onbind 是在客户端进程,所以也会进行binder 通信,会涉及对象序列化

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

    public final IBinder readStrongBinder() {
        return nativeReadStrongBinder(mNativePtr);
    }

/frameworks/base/core/jni/android_os_Parcel.cpp

调用native 层的方法

    {"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},

======
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {

// 调用 javaObjectForIBinder
// parcel->readStrongBinder() 传给 javaObjectForIBinder,所以驱动传来的对象可以和java 层对象互换
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}

调用 javaObjectForIBinder

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

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    // N.B. This function is called from a @FastNative JNI method, so don't take locks around
    // calls to Java code or block the calling thread for a long time for any reason.

    if (val == NULL) return NULL;

    if (val->checkSubclass(&gBinderOffsets)) {
        // 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
    BinderProxyNativeData* nativeData = new BinderProxyNativeData();
    nativeData->mOrgue = new DeathRecipientList;

// mObject  保存 val 指针
    nativeData->mObject = val;

// native 创建 BinderProxy对象
// 参数为 BinderProxyNativeData 和 val
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    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);
        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;
    }

// 返回 BinderProxy对象
    return object;
}

/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);
                if (result != null) {
                    return result;
                }

// 创建 BinderProxy 对象
                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;
    }

// 3)将返回的服务器的binder 对象传给客户端

/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        final long origId = Binder.clearCallingIdentity();
....
                    ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
                    for (int conni = connections.size() - 1; conni >= 0; conni--) {
                        ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                        for (int i=0; i<clist.size(); i++) {
                            ConnectionRecord c = clist.get(i);

                            try {

// c.conn 是前面传进来的,为 InnerConnection
// service 是服务端返回的对象
                                c.conn.connected(r.name, service, false);

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

        private static class InnerConnection extends IServiceConnection.Stub {
            @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

            InnerConnection(LoadedApk.ServiceDispatcher sd) {
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }

            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                }
            }
        }

=========
// 调用了 getServiceDispatcherCommon,传入的是应用进程的主线程handler【在 ContextImpl 的bindService】

        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
            } else if (mActivityThread != null) {

// mActivityThread 是handler 对象,让其在子线程去执行
                mActivityThread.post(new RunConnection(name, service, 0, dead));
        private final class RunConnection implements Runnable {
            RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
                mName = name;
                mService = service;
                mCommand = command;
                mDead = dead;
            }

            public void run() {
                if (mCommand == 0) {
                    doConnected(mName, mService, mDead);
                } else if (mCommand == 1) {
                    doDeath(mName, mService);
                }
            }

======================
        public void doConnected(ComponentName name, IBinder service, boolean dead) {
            ServiceDispatcher.ConnectionInfo old;
            ServiceDispatcher.ConnectionInfo info;

            synchronized (this) {
                if (mForgotten) {
                    // We unbound before receiving the connection; ignore
                    // any connection received.
                    return;
                }
                old = mActiveConnections.get(name);
                if (old != null && old.binder == service) {
                    // Huh, already have this one.  Oh well!
                    return;
                }

                if (service != null) {
                    // A new service is being connected... set it all up.
                    info = new ConnectionInfo();
                    info.binder = service;
                    info.deathMonitor = new DeathMonitor(name, service);
                    try {
                        service.linkToDeath(info.deathMonitor, 0);
                        mActiveConnections.put(name, info);
                    } catch (RemoteException e) {
                        // This service was dead before we got it...  just
                        // don't do anything with it.
                        mActiveConnections.remove(name);
                        return;
                    }

                } else {
                    // The named service is being disconnected... clean up.
                    mActiveConnections.remove(name);
                }

                if (old != null) {
                    old.binder.unlinkToDeath(old.deathMonitor, 0);
                }
            }

            // If there was an old service, it is now disconnected.
            if (old != null) {
                mConnection.onServiceDisconnected(name);
            }
            if (dead) {
                mConnection.onBindingDied(name);
            } else {
                // If there is a new viable service, it is now connected.
                if (service != null) {

// 回调 onServiceConnected 方法,将服务器端的 binder 对象给到客户端
// mConnection在创建 ServiceDispatcher 对象是有赋值,是 new ServiceConnection
                    mConnection.onServiceConnected(name, service);
                } else {
                    // The binding machinery worked, but the remote returned null from onBind().
                    mConnection.onNullBinding(name);
                }
            }
        }

到客户端,设置 mRemoteService = IRemoteService.Stub.asInterface(service)

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            mRemoteService = IRemoteService.Stub.asInterface(service);

=========
public interface IRemoteService extends android.os.IInterface {

    public static abstract class Stub extends android.os.Binder implements com.binderdemo.IRemoteService {

        private static final java.lang.String DESCRIPTOR = "com.binderdemo.IRemoteService";

        /**
         * Stub构造函数
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * 将IBinder 转换为IRemoteService interface
         */

// obj 是服务器端返回的 RemoteService 对象
        public static com.binderdemo.IRemoteService asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }

// 看是不是同一个进程
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.binderdemo.IRemoteService))) {
                return ((com.binderdemo.IRemoteService) iin);
            }

// 包装一下这个 obj
            return new com.binderdemo.IRemoteService.Stub.Proxy(obj);
        }

// 包装一下这个 obj

        private static class Proxy implements com.binderdemo.IRemoteService {
            private android.os.IBinder mRemote;

            /**
             * Proxy构造函数
             */
            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

// 通过 asBinder 接口就可以获取这个对象了
            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

IRemoteService.Stub.asInterface(service) 调用服务端的方法

如调用 getMyData() 方法

先看下 asInterface 方法:

        public static com.binderdemo.IRemoteService asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.binderdemo.IRemoteService))) {
                return ((com.binderdemo.IRemoteService) iin);
            }

// 由于是 不同进程,则用 Proxy 包装这个 obj,obj 由上面分析是 BinderProxy
            return new com.binderdemo.IRemoteService.Stub.Proxy(obj);
        }

// ================ 静态的 Proxy 类 ================
        private static class Proxy implements com.binderdemo.IRemoteService {
            private android.os.IBinder mRemote;

            /**
             * Proxy构造函数 设置 mRemote 为 BinderProxy
             */
            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public int getPid() 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);

// 调用 BinderProxy 的 transact 方法
                    mRemote.transact(Stub.TRANSACTION_getPid, _data, _reply, 0);

// _reply 是服务端传过来的值
                    _reply.readException();
                    _result = _reply.readInt();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }

asInterface作为 BinderProxy的代理接口,调用了 BinderProxy 的 transact 方法。最终会调用到服务端的类,该类继承了静态的 Stub 类,实现了 onTransact方法。

从AIDL到内核,一次完整的Binder通信 - 掘金

借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/529766.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

shell编程:概述、脚本入门、变量、运算符、条件判断、流程控制、读取控制台、函数、正则表达式、文本处理工具、综合案例

第 1 章 Shell 概述 1&#xff09;Linux 提供的 Shell 解析器有 [atguiguhadoop101 ~]$ cat /etc/shells /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash /bin/tcsh /bin/csh2&#xff09;bash 和 sh 的关系 sh&#xff1a;比较基础bash&#xff1a;功能更加强大&#xff0c;默…

三十四、Hybrid 接口用法解析

文章目录 前言交换机接口类型有哪些Hybrid 端口使用场景什么时候必须使用 Hybrid 一、Hybrid 特点二、Hybrid 当做 access和trunk使用三、Hybrid 特殊用法 前言 交换机接口类型有哪些 Access、trunk、Hybrid、qinq Hybrid 端口使用场景 接pc、服务器、接交换机、接路由器&a…

Linux守护进程

"忍耐的灵魂啊&#xff0c;安静地运转吧~" 我们先来看看这个场景。这是一个常见的基于TCP套接字的网络服务器&#xff0c;服务端接收客户端发送的消息&#xff0c;收到后并向echo回响给客户端。 对于Linux而言&#xff0c;终端只能有一个前台进程&#xff0c;这也是为…

行业唯一丨冠珠出席“中国企业社会责任高峰论坛”,并荣获人民日报社“ESG年度案例”

践行社会责任&#xff0c;推动品牌高质量发展。5月11日&#xff0c;由人民日报社指导、人民日报社经济社会部主办的“中国企业社会责任高峰论坛”在上海盛大举行。 本次论坛围绕乡村振兴、共同富裕、绿色低碳等重点议题进行深入研讨&#xff0c;邀请国家发展和改革委员会、商务…

教程硬货|微信小程序开发之基于vue的微信开发工具JS文件解读(一)

文章目录 1 前言2 前期准备3 微信开发者工具3.1 创建项目3.2 页面介绍 4 读懂Pages4.1 index.wxss4.2 index.wxml4.3 index.json4.4 index.js 5 logs6 小程序的主要文件6.1 app.js6.2 app.json 7 讨论 1 前言 鉴于前段时间出的第一篇记录安装Nodejs和HBuilderX搭建、部署微信小…

【C++】内存分区模型

目录 1、缘起 2、内存分区模型 2.1、程序运行前 2.2、程序运行后 3、总结 1、缘起 前几天学习完了 C 的 基础语法 知识点&#xff0c;现在终于要踏上学习 C 核心编程 的旅程了&#xff0c;期待沿途中所遇到的风景。 2、内存分区模型 C 程序在执行时&#xff0c;将内存大…

【Python Cookie 和代理 IP】零基础也能轻松掌握的学习路线与参考资料

一、Python Cookie 1、什么是Cookie&#xff1f; Cookie是一种在客户端保存数据的机制&#xff0c;服务器通过在HTTP响应头中添加Set-Cookie头实现。浏览器在接收到响应头中的Set-Cookie后&#xff0c;会将这个Cookie保存在本地。之后每次请求都会将本地保存的Cookie自动添加…

WPF插件之 - PropertyChanged.Fody插件的使用详解

总目录 文章目录 总目录一、PropertyChanged.Fody是什么&#xff1f;二、PropertyChanged.Fody的安装三、PropertyChanged.Fody的功能1. 特性1 实现属性通知的功能2 通知其他属性4 不进行属性通知3 指定属性更改时将调用的方法5 设置当前属性依赖的属性6 不检查是否相等7 DoNot…

lua:浅谈对元表和元方法的认识

前言 本篇在讲什么 浅谈对Lua元表和元方法的理解 本篇适合什么 适合初学Lua的小白 本篇需要什么 对Lua语法有简单认知 依赖Lua5.1的环境 依赖Sublime Text3编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码…

ETCD实现分布式锁

分布式锁具备特点 互斥性&#xff1a;在同一时刻&#xff0c;只有一个客户端能持有锁 安全性&#xff1a;避免死锁&#xff0c;如果某个客户端获得锁之后处理时间超过最大约定时间&#xff0c;或者持锁期间发生了故障导致无法主动释放锁&#xff0c;其持有的锁也能够被其他机制…

ANR实战案例 - FCM拉活启动优化

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 文章目录 系列文章目录前言一、Trace日志分析二、业务分析1.Firebase源码分析2.Firebase官方查看官方文档Dem…

数据压缩新利器!小精灵ELF助你高效存储与传输

存储空间不够用&#xff1f;网络传输太慢&#xff1f;想必每个人在生活中都会遇到这些问题。看着爆满的硬盘、焦急的等待数据的接受&#xff0c;更新设备&#xff1f;不是每个人都能承担这个成本。那不如尝试一下无损压缩&#xff1f; 为了减少存储空间的占用&#xff0c;提高…

《Netty》从零开始学netty源码(五十七)之ServerBootstrap.bind()

目录 ServerBootstrap.bind()initAndRegister()init()register()doBind0() ServerBootstrap.bind() 在第一篇的HelloWorld中通过ServerBootstrap.bind()方法绑定端口号并最终启动Netty的服务&#xff0c;服务端的bind过程如下&#xff1a; 上面的代码主要分成两部分&#xff0…

【P20】JMeter XPath提取器(XPath Extractor)

文章目录 一、准备工作二、测试计划 一、准备工作 百度&#xff1a;https://www.w3school.com.cn/example/xmle/cd_catalog.xml 进入网页后&#xff0c;右键检查或按F12&#xff0c;打开调试工具 如图&#xff0c;使用XPath提取器&#xff08;XPath Extractor&#xff09;获取…

typescript学习笔记(下)

1、类型拓宽 所有通过 let 或 var 定义的变量、函数的形参、对象的非只读属性&#xff0c;如果满足指定了初始值且未显式添加类型注解的条件&#xff0c;那么它们推断出来的类型就是指定的初始值字面量类型拓宽后的类型&#xff0c;这就是字面量类型拓宽。 下面我们通过字符串…

数据结构-排序-(选择、堆排序、归并排序、基数排序)

目录 一、选择排序 二、堆排序 排序 效率分析 三、归并排序 排序 分析 四、基数排序 一、选择排序 思想&#xff1a;每趟在待排序元素中选取关键字最小的元素加入有序子列 不稳定性 空间复杂度&#xff1a;O(1) 时间复杂度&#xff1a; void swap(int &a,int &…

[Linux] 动态 / 静态库的生成与使用

文章目录 简要概念 静态库生成使用 动态库生成使用 简要概念 库一般分为两种&#xff1a; 静态库动态库 在 Linux 中&#xff1a; 如果是动态库&#xff0c;库文件是以 .so 作后缀的如果是静态库&#xff0c;库文件是以 .a 作后缀的 库文件的命名&#xff1a; libXXX.so …

RBTree

目录 红黑树的概念 红黑树性质 红黑树节点设计 红黑树的插入 红黑树的验证 红黑树和AVL树的比较 红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或 Black。 通过对任何一条从根到叶子的…

Point-SLAM: Dense Neural Point Cloud-based SLAM阅读记录

前言 只读了前半部分就感慨文章结构真的好清晰&#xff0c;从Introduction到related work完完全全都在体现它的motivation——他做了一件什么事情&#xff1f;以及为什么要这么做&#xff1f;解决了什么问题。 第一遍阅读 keywords: 以RGBD作为输入 使用点云表示场景的 dens…

【P21】JMeter XPath2 提取器(XPath2 Extractor)

文章目录 一、准备工作二、测试计划 一、准备工作 百度&#xff1a;https://www.w3school.com.cn/example/xmle/cd_catalog.xml 进入网页后&#xff0c;右键检查或按F12&#xff0c;打开调试工具 如图&#xff0c;使用XPath2 提取器&#xff08;XPath2 Extractor&#xff09;…