返回顶部
首页 > 资讯 > 移动开发 >Android Framework如何实现Binder
  • 287
分享到

Android Framework如何实现Binder

2024-04-02 19:04:59 287人浏览 八月长安
摘要

目录Framework如何实现BinderServiceManager小结Binder结构Framework如何实现Binder 为了日常的使用framework层同样实现了一套bi

Framework如何实现Binder

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

ServiceManager

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

    public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }
    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }
​
        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }
public final class ServiceManagerNative {
    private ServiceManagerNative() {}
​
    
    @UnsupportedAppUsage
    public static IServiceManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        // ServiceManager is never local
        return new ServiceManagerProxy(obj);
    }
}

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

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

是个native方法

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

小结

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

Binder结构

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

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

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

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

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

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

关键就在JavaBBinderHolder的get方法了:

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

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

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

--结束END--

本文标题: Android Framework如何实现Binder

本文链接: https://lsjlt.com/news/167600.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android Framework如何实现Binder
    目录Framework如何实现BinderServiceManager小结Binder结构Framework如何实现Binder 为了日常的使用framework层同样实现了一套bi...
    99+
    2024-04-02
  • Android Framework原理Binder驱动源码解析
    目录引言1 system_server和service_manager的关系2 传统IPC与Binder之间的区别3 物理内存和虚拟内存4 Binder驱动源码分析4.1 binde...
    99+
    2023-01-30
    Android Framework Binder驱动 Android Framework
  • 【Android Framework系列】第2章 Binder机制大全
    1 Binder简介 1.1 什么是Binder   Binder是Android中主要的跨进程通信方式。Android系统中,每个应用程序是由Android的Activity,Service,Bro...
    99+
    2023-09-12
    android binder Framework
  • Android Framework原理Binder驱动源码是什么
    今天小编给大家分享一下Android Framework原理Binder驱动源码是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们...
    99+
    2023-07-05
  • 【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例
    Binder介绍 Android 中的 Binder 是一个进程间通信机制,它允许不同进程之间相互调用方法和传递数据。Binder 主要用于实现系统服务和应用程序之间的通信,以及实现 IPC(Inte...
    99+
    2023-09-03
    android binder 网络
  • 全网最全Android Framework框架总结,Android如何入门Framework层
    每一个Android开发,基本都了解或者学习过系统的知识,一是因为国内软件行业内卷,找工作时“面试造火箭,工作拧螺丝”的局面导致的,另一方面,从客观角度来讲,学习Android系统、Framework...
    99+
    2023-08-31
    android android studio ide
  • Android通过继承Binder类实现多进程通信
    AIDL的底层是通过Binder进行通信的,通过追踪.aidl编译后自动生成的文件我们知道,文件中的Stub类用于服务端,Proxy类用于客户端调用,那么可否直接通过继承Bin...
    99+
    2022-06-06
    进程 binder 多进程 通信 Android
  • Entity Framework Core如何实现表名映射
    小编给大家分享一下Entity Framework Core如何实现表名映射,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!表名映射我们知道:如果是在默认情况下,使用EFCore Code First的方...
    99+
    2023-06-29
  • Android Binder机制浅谈以及使用Binder进行跨进程通信的俩种方式(AIDL以及直接利用Binder的transact方法实现)
    Binder机制学习 Binder机制是Android进行IPC(进程间通信)的主要方式Binder跨进程通信机制:基于C/S架构,由Client、Server、ServerManager和Binder驱动组成。 进程空间分为用户空间和...
    99+
    2023-08-16
    android binder java AIDL Binder跨进程通信
  • Android中的多进程通信怎么利用继承Binder类实现
    Android中的多进程通信怎么利用继承Binder类实现?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。服务端代码,BinderService.java:首先继...
    99+
    2023-05-31
    android 多进程 binder
  • 我是如何从Android开发转framework开发的
    转framework开发快一年了,一直都想写一篇文章,分享一下自己的工作心得,也让做应用开发的小伙伴对framework开发有一定的了解,但因为种种原因耽搁了,今天就趁着工作闲暇之余,聊聊我从应用开发转framework开发的心路历程,自己...
    99+
    2023-08-16
    android
  • Entity Framework实现数据迁移
    一、合并和迁移 1、合并 合并是指“新的实体模型映射到数据库中,更新其结构”,例如:新增了实体类,表现在数据库中就是新增加实体类对应的数据表。删除了实体类,表...
    99+
    2024-04-02
  • Hibernate Framework查询怎么实现
    本篇内容主要讲解“Hibernate Framework查询怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hibernate Framework查询怎么实现”吧!Hibernate&nb...
    99+
    2023-06-17
  • Entity Framework如何使用LINQ操作实体
    这篇文章将为大家详细讲解有关Entity Framework如何使用LINQ操作实体,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、什么是LINQ TO EntitiesLINQ,全称是Lan...
    99+
    2023-06-29
  • Android中如何实现OKHttp
    这篇文章将为大家详细讲解有关Android中如何实现OKHttp,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。下面是官网给出的OKHTTP的特点:支持HTTP/2, HTTP/2通过使用多路复用技术在一个...
    99+
    2023-06-15
  • Android中使用socket使底层和framework通信的实现方法
    一般的native和framework的通信是通过jni,但是这一般只是framework调用native,native如果有消息要怎样通知上层 呢?android中GSP模块...
    99+
    2022-06-06
    方法 framework socket Android
  • Entity Framework中如何使用DataBase First模式实现增删改查
    本篇内容主要讲解“Entity Framework中如何使用DataBase First模式实现增删改查”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Entity ...
    99+
    2023-06-29
  • android菜单menu如何实现
    在Android中,可以通过以下步骤来实现菜单(Menu):1. 在res目录下的menu文件夹中创建一个XML文件,用于定义菜单的...
    99+
    2023-09-22
    android
  • Android如何实现备忘录
    这篇文章主要介绍了Android如何实现备忘录,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档一、首先创建保存数...
    99+
    2023-06-25
  • Android如何实现加载圈
    这篇文章主要介绍“Android如何实现加载圈”,在日常操作中,相信很多人在Android如何实现加载圈问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android如何实现加载圈”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作