Android10.0 Binder通信原理(八)-Framework层分析

2023-10-31

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

[Android取经之路] 系列文章:

《系统启动篇》

Android系统架构
Android是怎么启动的
Android 10.0系统启动之init进程
Android10.0系统启动之Zygote进程
Android 10.0 系统启动之SystemServer进程
Android 10.0 系统服务之ActivityMnagerService
Android10.0系统启动之Launcher(桌面)启动流程
Android10.0应用进程创建过程以及Zygote的fork流程
Android 10.0 PackageManagerService(一)工作原理及启动流程
Android 10.0 PackageManagerService(二)权限扫描
Android 10.0 PackageManagerService(三)APK扫描
Android 10.0 PackageManagerService(四)APK安装流程
《日志系统篇》

Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​
《Binder通信原理》:

Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
Android10.0 Binder通信原理(二)-Binder入门篇
Android10.0 Binder通信原理(三)-ServiceManager篇
Android10.0 Binder通信原理(四)-Native-C\C++实例分析
Android10.0 Binder通信原理(五)-Binder驱动分析
Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
Android10.0 Binder通信原理(七)-Framework binder示例
Android10.0 Binder通信原理(八)-Framework层分析
Android10.0 Binder通信原理(九)-AIDL Binder示例
Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
Android10.0 Binder通信原理(十一)-Binder总结

《HwBinder通信原理》

HwBinder入门篇-Android10.0 HwBinder通信原理(一)
 HIDL详解-Android10.0 HwBinder通信原理(二)
HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
HwServiceManager篇-Android10.0 HwBinder通信原理(五)
Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
HwBinder原理总结-Android10.0 HwBinder通信原理(十一)
《编译原理》

编译系统入门篇-Android10.0编译系统(一)
编译环境初始化-Android10.0编译系统(二)
make编译过程-Android10.0编译系统(三)
Image打包流程-Android10.0编译系统(四
Kati详解-Android10.0编译系统(五)
Blueprint简介-Android10.0编译系统(六)
Blueprint代码详细分析-Android10.0编译系统(七)
Android.bp 语法浅析-Android10.0编译系统(八)
Ninja简介-Android10.0编译系统(九)
Ninja提升编译速度的方法-Android10.0编译系统(十)
Android10.0编译系统(十一)

1.概述
前面几节,我们已经把Native层和Binder驱动层的Binder数据流转给理清楚了,也知道了相应的概念。这一节让我们继续往上进行分析,我们进入到Framework层,看看Framework是如何实现服务的注册、获取的流程。

2.Binder架构
Framework层要实现服务的注册需要通过JNI 来调用Native C\C++层的相应接口,最终把服务注册到Native层的ServiceManager中。
应用层的进行通过Framework的接口,也经过JNI技术进入Native C\C++,最终在Native层的ServiceManager中得到服务handle,最终转成相应的服务对象。

3.源码分析
3.1 Binder-JNI
当Init进程启动后,孵化Zygote进程时,会有一个虚拟机注册过程,在这个过程中完成了JNI的注册,我们现在不需要深入去理解JNI的原理,后面有时间,我再单独出一章来进行分析。

现在我们只要知道 JAVA和Native侧的函数对应关系在哪里即可。

Binder的JNI中有个三个Binder的映射数组:gBinderMethods、gBinderInternalMethods、gBinderInternalMethods。

我们在撸代码时,是要根据JAVA的函数入口找到JNI的函数调用即可,不要太追求细枝末节。

gBinderMethods:
 

[/frameworks/base/core/jni/android_util_Binder.cpp]
static const JNINativeMethod gBinderMethods[] = {
     /* name, signature, funcPtr */
    // @CriticalNative
    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
    // @CriticalNative
    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
    // @CriticalNative
    { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction },
    // @CriticalNative
    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
    // @CriticalNative
    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
    // @CriticalNative
    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
    // @CriticalNative
    { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
    // @CriticalNative
    { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
    // @CriticalNative
    { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
    { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
    { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
    { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
    { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};

gBinderInternalMethods:

[/frameworks/base/core/jni/android_util_Binder.cpp]
static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
    { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
    { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
    { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
    { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
};

gBinderInternalMethods:

[/frameworks/base/core/jni/android_util_Binder.cpp]
static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
    { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
    { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
    { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
    { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
};

3.2 服务注册

在上一节的Framework Binder Demo示例中,我们知道服务注册的时候,调用的是ServiceManager.java的addService(),那我们就拿addService()开刀。

注册服务调用栈:

 

3.2.1 addService()

[/frameworks/base/core/java/android/os/ServiceManager.java]
public static void addService(String name, IBinder service, boolean allowIsolated,
        int dumpPriority) {
    try {
        //获取ServiceManagerProxy对象,执行addService操作
        getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
}

拿到ServiceManagerProxy对象,来执行addService操作,这个ServiceManagerProxy对象需要我们来揭开面纱。

3.2.2 getIServiceManager()

[/frameworks/base/core/java/android/os/ServiceManager.java]
private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }
 
    // Find the service manager
    sServiceManager = ServiceManagerNative
            .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

这里也采用了单例模式来获取ServiceManagerProxy对象,减少对象重复创建。

[/frameworks/base/core/java/android/os/ServiceManagerNative.java]
static public IServiceManager asInterface(IBinder obj)
{
    if (obj == null) {
        return null;
    }
    IServiceManager in =
        (IServiceManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
 
    return new ServiceManagerProxy(obj);
}

asInterface()中的主要作用就是创建ServiceManagerProxy()对象,但是需要带一个IBinder的 obj,我来看看这个obj是如何拿到的。

3.2.3 getContextObject()

 

[/frameworks/base/core/java/com/android/internal/os/BinderInternal.java]
public static final native IBinder getContextObject();

BinderInternal.java中有一个native方法getContextObject(),JNI调用执行上述方法,在JNI的 gBinderInternalMethods数组中找到了getContextObject的对应关系,即为android_os_BinderInternal_getContextObject。
 

android_os_BinderInternal_getContextObject()
[/frameworks/base/core/jni/android_util_Binder.cpp]
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}

ProcessState::self()->getContextObject(NULL) 在《Binder--Native-C\C++实例分析》 的[5.3.1]节已经进行了详细分析,最终等价于 new BpBinder(0),这里就不重复展开了。

 

javaObjectForIBinder()

如果参数是JavaBBinder,返回用于创建它的Java对象;否则返回一个BinderProxy的对象。

如果上一个调用被传递给同一个IBinder,而原来的BinderProxy还活着,返回同样的BinderProxy。
 

[/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)) {
            //如果参数是JavaBBinder,返回用于创建它的Java对象;否则返回一个BinderProxy的对象。
        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;
    nativeData->mObject = val;
 
    //创建BinderProxy对象,设置BinderProxy的相关参数,能够与JAVA层的BinderProx参与工作
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    if (env->ExceptionCheck()) {
        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) {
            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;
}

javaObjectForIBinder()中,申请一个BinderProxyNativeData的内存,传入的BpBinder的对象地址保存到BinderProxyNativeData.mObject成员变量中,通过虚拟机的转换,BinderProxyNativeData在JAVA空间会被转换成 BinderProxy对象。

最终,BinderInternal.getContextObject()等价于 new BinderProxy(),所以getIServiceManager等价于new ServiceManagerProxy(new BinderProxy())。

 
3.2.4 ServiceManagerProxy.addService()
上一节,我们已经拿到了ServiceManager在JAVA空间的代理,即ServiceManagerProxy,接着调用addService()来进行服务的注册。
 

[/frameworks/base/core/java/android/os/IServiceManager.java]
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);
    //将Binder对象扁平化,转换成flat_binder_object对象,这里为服务注册,对应的是Binder实体
    data.writeStrongBinder(service); 
    data.writeInt(allowIsolated ? 1 : 0);
    data.writeInt(dumpPriority);
       //Code:ADD_SERVICE_TRANSACTION ,parcel的数据 发到C空间,进行事务处理,注册服务。
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); 
    reply.recycle();
    data.recycle();
}

组装一个Parcel数据,把服务的名称和对象写入Parcel中,然后把它拍扁,服务转成flat_binder_object对象,在Native层为Binder实体。

 

3.2.5  writeStrongBinder()
把传入的服务对象拍扁,转成flat_binder_object对象,代码流程太罗嗦,这里列出以下调用栈流程:

 

data.writeStrongBinder(service)等价于parcel->writeStrongBinder(new JavaBBinder(env, obj));最终调用的是flatten_binder(),目的是把一个Binder实体“压扁”并写入Parcel。

这里"压扁"的含义,其实就是把Binder对象整理成flat_binder_object变量。如果压扁的是Binder实体,那么flat_binder_object用cookie域记录binder实体的指针,即BBinder指针,而如果打扁的是Binder代理,那么flat_binder_object用handle域记录的binder代理的句柄值。

接着flatten_binder()调用了一个关键的finish_flatten_binder()函数。这个函数内部会记录下刚刚被扁平化的flat_binder_object在parcel中的位置。说得更详细点儿就是,parcel对象内部会有一个buffer,记录着parcel中所有扁平化的数据,有些扁平数据是普通数据,而另一些扁平数据则记录着binder对象。所以parcel中会构造另一个mObjects数组,专门记录那些binder扁平数据所在的位置,示意图如下:

flatten_binder()的流程可以参考《Binder--Native-C\C++实例分析》 的[5.4]节

 

3.2.6 mRemote对象

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }
    @UnsupportedAppUsage
    private IBinder mRemote;
}

mRemote 是ServiceManagerProxy的一个成员,执行一个IBinder对象,mRemote在ServiceManagerProxy()构造函数中进行了赋值,从[4.2.3]和[4.2.4] 可知getIServiceManager()中调用了 如下内容:

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

从而可知 mRemote = BinderInternal.getContextObject() = new BinderProxy(),所以mRemote就是BinderProxy的对象。

mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0) 等价于BinderProxy.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)

 
3.2.7 BiderProxy.transact()
 

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        //检查Parcel的大小是否大于800K
    Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
 
    try {
        return transactNative(code, data, reply, flags);
    } finally {
            ...
    }
}

逻辑很简单,先检查Parcel的大小是否大于800K,然后调用了transactNative()进行数据传递。 

public native boolean transactNative(int code, Parcel data, Parcel reply,
        int flags) throws RemoteException;
逻辑很简单,先检查Parcel的大小是否大于800K,然后调用了transactNative()进行数据传递。
public native boolean transactNative(int code, Parcel data, Parcel reply,
        int flags) throws RemoteException;

transactNative()一个Native方法,根据之前的JNI数组表,可以查到JNI的对应入口。

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();
    ...
        //根据我们之前获取的对象流程来看,BinderProxy在Native空间,对应的是BpBinder,target即为BpBinder对象
    status_t err = target->transact(code, *data, reply, flags);
    ...
    return JNI_FALSE;
}

根据我们之前获取的对象流程来看,BinderProxy在Native空间,对应的是BpBinder,target即为BpBinder对象。所以target->transact() 等价于BpBinder::transact(), 接下来的流程参考前面Native-C\C++层的分析,这里的细节不再阐述,参考 《Binder--Native-C\C++实例分析》 和 《Binder数据如何定向打击》,也可以看到上面注册服务的调用栈。

 

3.2.8 服务注册总结
framework层的ServiceManager的调用实际的工作确实交给ServiceManagerProxy的成员变量BinderProxy;而BinderProxy通过jni方式,最终会调用BpBinder对象;可见上层binder架构的核心功能依赖native架构的服务来完成的。

注册服务的核心部分,就是JAVA侧把服务名称和对象,转入Parcel“扁平”数据,通过Native BpBinder,把code:ADD_SERVICE_TRANSACTION发给Binder驱动,再转到Native的ServiceManager,ServiceManager把服务名称和转换后的handler进行存储,供Client进行服务获取。

 

3.3 服务获取

在上一节的Framework Binder Demo示例中,我们知道服务注册的时候,调用的是ServiceManager.java的getService(),那么获取服务就从getService()入口。

[/frameworks/base/core/java/android/os/ServiceManager.java]
public static IBinder getService(String name) {
    try {
            //从缓存中获取服务对象
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
                 //从Native层服务列表中取服务对象
            return Binder.allowBlocking(rawGetService(name));
        }
    } catch (RemoteException e) {
        Log.e(TAG, "error in getService", e);
    }
    return null;
}

3.3.2 rawGetService()

[/frameworks/base/core/java/android/os/ServiceManager.java]
private static IBinder rawGetService(String name) throws RemoteException {
    ...
        //
        //即为ServiceManagerProxy().getService
    final IBinder binder = getIServiceManager().getService(name);
    ...
    return binder;
}

从上面可知getIServiceManager() 等价于 new ServiceManagerProxy(new BinderProxy()),getIServiceManager().getService(name)等价于ServiceManagerProxy().getService(name)

 

3.3.3 getService()
 

[/frameworks/base/core/java/android/os/ServiceManagerNative.java]
public IBinder getService(String name) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
    mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
    IBinder binder = reply.readStrongBinder();
    reply.recycle();
    data.recycle();
    return binder;
}

从[4.2.6]可知,mRemote.transact(XXX) 等价于BinderProxy.transact(xx),这里不展开,和[4.2.7流程]一样,只是ServiceManager获取到服务的handle后,存入了reply信息中,这里会再调用reply.readStrongBinder()把binder对象给取出来。

 

3.3.4 readStrongBinder()
 

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

调用栈如下:

 


Parcel.cpp -> readStrongBinder() 参考 《Binder--Native-C\C++实例分析》 中的[6.4]节,  javaObjectForIBinder()参考[4.2.3]

readStrongBinder()最终是从reply的Parcel数据中获得BpBinder对象,再转成BinderProxy对象,参与JAVA层的工作。

 
3.3.5 allowBlocking
 

[/frameworks/base/core/java/android/os/Binder.java]
public static IBinder allowBlocking(IBinder binder) {
    try {
        //如果binder是代理类,则设置非阻塞式
        if (binder instanceof BinderProxy) {
            ((BinderProxy) binder).mWarnOnBlocking = false;
        } else if (binder != null && binder.getInterfaceDescriptor() != null
                && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
            //如果binder是本地对象,binder描述符不为空,且和本地binder描述符不相同 
            Log.w(TAG, "Unable to allow blocking on interface " + binder);
        }
    } catch (RemoteException ignored) {
    }
    return binder;
}

作用:

允许在给定接口上阻塞调用,重写请求的{setWarnOnBlocking(boolean)}值。
只有当您完全确定远程接口是一个永远无法升级的内置系统组件时,才应该很少调用此命令。尤其是,决不能对包托管的、可升级或替换的接口调用此命令,否则,如果远程接口接入,将有系统不稳定的风险。
3.3.6 获取服务小结
和注册服务类似,都是需要依赖Native层的接口与Binder驱动通信,获取服务主要是从Native的ServieManager取到Binder对象。

 

3.4 Client-Server接口调用
在[3.2] 和[3.3]中,我们知道了服务注册addService()和获取服务getService()的流程,接下来我们再看一看接口调用是如何进行的。
 

[MyServiceProxy.java]
public void setValue(String str) throws RemoteException {
    Parcel data = Parcel.obtain(); //准备发送数据,结构为Parcel
    Parcel reply = Parcel.obtain();//准备返回数据,结构为Parcel
    try {
            //写入服务的Token,用来验证服务的准确性
        data.writeInterfaceToken(IMyService.descriptor); 
        data.writeString(str); //把参数写入Parcel,服务端会获取该参数
        mRemote.transact(SET_VALUE_TRANSACTION, data, reply, 0); //code:SET_VALUE_TRANSACTION
        reply.readException();
    } finally {
        reply.recycle();
        data.recycle();
    }
}

上面调用的流程,其实和addService()、getService()类似,都是组装Parcel数据,准备服务端的code,调用BinderProxy.transact()发送到服务端。

但是和服务注册不同的是,在服务注册中,Native的ServiceManager是Server端,服务实体是Client端。接口调用时,服务实体是Server端。

服务端接收到CLient的请求后,根据下图的流程,最终流转到服务实体的onTransact()中,对解析出来的Parcel数据进行处理。

4.总结
Framework层获取服务、注册服务,其实都是由JAVA层的ServiceManager代理 ServiecManagerProxy ,通过Binder驱动,访问Native层的ServiceManager,进行服务注册和获取动作。

这一节只是单独在Framework层进行了分析,很多情况下我们都是在应用层进行处理流程,通过AIDL接口进行通信,下一节会对AIDL进行一下分析。

 

代码路径:

Framework:

/frameworks/base/core/java/android/os/Binder.java
/frameworks/base/core/java/android/os/IBinder.java
/frameworks/base/core/java/android/os/BinderProxy.java
/frameworks/base/core/java/android/os/BinderProxy.java
/frameworks/base/core/java/android/os/ServiceManager.java
/frameworks/base/core/java/android/os/IServiceManager.java
/frameworks/base/core/java/android/os/ServiceManagerNative.java
/frameworks/base/core/java/com/android/internal/os/BinderInternal.java

JNI:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android10.0 Binder通信原理(八)-Framework层分析 的相关文章

随机推荐

  • 网络编程套接字,Linux下实现echo服务器和客户端

    目录 1 一些网络中的名词 1 1 IP地址 1 2 端口号port 1 3 端口号 和 进程ID 1 4 初始TCP协议 1 5 UDP协议 2 socket编程接口 2 1 socket 常见API 2 2 sockaddr结构 3 简
  • chatgpt赋能python:Python手动安装whl文件的方法

    Python手动安装whl文件的方法 Python是目前最为流行的编程语言之一 广泛应用于数据分析 AI Web开发等领域 Python的强大之处不仅在于其灵活的语法 更在于丰富的第三方库资源 这些库资源往往以 whl文件格式提供 而手动安
  • kali linux破解wifi密码-超详细过程

    前期准备 VMware Workstation虚拟机 在虚拟机安装好kail linunx系统 无线网卡 芯片为3070或者1887L都支持Linux 或者直接某宝上查kali无线网卡 一 打开终端 用airmon ng命令查看 如果出现无
  • Matplotlib学习---用matplotlib画散点图,气泡图(scatter plot, bubble chart)

    Matplotlib里有两种画散点图的方法 一种是用ax plot画 一种是用ax scatter画 一 用ax plot画 ax plot x y marker o color black 二 用ax scatter画 ax scatte
  • jav中spark迁移hive到mongo(更新数据)

    业务中的数据库使用的mongo 离线使用spark计算的每天统计指标需要累加到历史指标中 然后将结果写到mongo库中 如果mongo库中已经有这条记录则覆盖 mongo库中没有此记录则为新增 我们如果根据 MongoSpark save
  • StringUtils.isAnyBlank() StringUtils.isNoneBlank()

    StringUtils isAnyBlank 是否包含任何真空值 包含空格或空值 StringUtils isAnyBlank null true StringUtils isAnyBlank null foo true StringUti
  • Dapp开发教程一 Asch Dapp Hello World

    1 基本流程 Asch有三种net localnet testnet mainnet 后两种是发布到线上的 可通过公网访问 第一种localnet是运行在本地的 只有一个节点的私链 主要是为了方便本地测试和开发 Dapp的开发同样要涉及到这
  • HDFS的副本数量配置

    众所周知 hdfs的默认副本数量是3个 配置在 etc hadoop conf hdfs site xml中
  • uni-app多端开发注意事项

    关于vue 1 注意 如果使用老版的非自定义组件模式 即manifest中 usingComponents false 部分模版语法不支持 但此模式已于2019年11月起下线 2 data 必须声明为返回一个初始数据对象的函数 否则页面关闭
  • iOS进阶—Runtime基础

    iOS进阶 目录 GitHub参考 RunTime 基础 一个程序的执行过程 大概就是代码 gt 编译链接 gt 执行 C语言 import
  • Acwing-4645. 选数异或

    暴力解法 TLE了 呜呜呜呜 include
  • Linux系统下安装Redis

    文章目录 下载Redis 上传至Linux服务器 安装Redis 基本环境安装 运行Redis redis benchmark性能测试 下载Redis 下载地址 https redis io 上传至Linux服务器 可借助任何一款ftp软件
  • IT人员必学最基础知识(一)——总括

    作为一个真正的IT人员 我们不仅要懂得高级语言的编程使用 更要懂得电脑最基础的知识 这是我们成为杰出的IT人员的基石 只要踏上这些基础知识我们才能走的更高 首先我们要懂得电脑是如何工作的 大千世界无奇不有 繁彩纷呈 而一台小小的电脑就可以处
  • 算法入门:双指针法

    一 双指针法 例子1 求一个有序数组中和 8的下标 设置两个不同的指针 或者头 或者尾 在一个递增的序列中 根据结果分类 说明指针的下一步应该怎么移动 结果分类 a i b j 8则i j 都相互靠近 a i b j lt 8 需要移动指针
  • 使用react-grid-layout和echarts-for-react实现一个支持拖拽的自定义响应式dashboard页面

    文章目录 使用react grid layout和echarts for react实现一个支持拖拽的自定义响应式dashboard页面 需求概要 技术栈 简单实现 参考 使用react grid layout和echarts for re
  • python画聚类树状图_聚类分析python画树状图--Plotly(dendrogram)用法解析

    1 前言 聚类分析是机器学习和数据分析中非常常见的分类方法 当我们用到层次聚类 系统聚类 时 最常用的分析方法就是绘制树状图 比较常见的统计软件像SPSS SAS R等都可以直接绘制树状图 比较简单 今天主要介绍下python怎么绘制 2
  • 校园欺凌——四位学生的乱伦之战!!!

    校园欺凌 Impossible 学生之战 Non existent 乱伦 Take leave ok 兄弟姊妹们 今天我们来学习循环结构第一章 gt gt gt While与Do Whlie 循环 重复得做某一件事情 Such as 打印5
  • QVariant的用法

    前言 QVariant这个类很神奇 或者说方便 很多时候 需要几种不同的数据类型需要传递 如果用结构体 又不大方便 容器保存的也只是一种数据类型 而QVariant则可以统统搞定 介绍 帮助文档上说 The QVariant class a
  • 云化背景下的接口测试覆盖率自动化检查

    一 问题来源 在云化场景下 API的测试覆盖是一项重要评估与考察指标 除了开发者自测试外 UT 还可以利用云化测试平台 流水线等方法进行相关指标的检查与考核 利用这种方法既可以减轻开发者测试工作量 不必在本地做大量的 降低人为指标灰度空间
  • Android10.0 Binder通信原理(八)-Framework层分析

    Android取经之路 的源码都基于Android Q 10 0 进行分析 Android取经之路 系列文章 系统启动篇 Android系统架构Android是怎么启动的Android 10 0系统启动之init进程Android10 0系