无法在这个位置找到: head2.htm
当前位置: 建站首页 > 产品 > 网站设计 >

湖南轿车小程序—大厂爱考的 Binder 系统服务注册问题怎么破?

时间:2021-02-11 03:47来源:未知 作者:湖南省轿车微信小 点击:
IMG公布课火爆袭来,手机上入门机手机游戏开发设计设计方案设计方案计划方案者决不会会能错过了了了的顶尖课堂教学课堂教学课堂教学课堂教学! 不是就是你由于手机上入门机手

IMG发布课受欢迎袭来,手机上手机游戏开发设计设计方案者决不会能错过了了的顶级课堂教学课堂教学! 是不是你因为手机上手机游戏页面模糊不清不清不清、头疼不己却又不知道道道如何变更?锁定一月22日网上发布课,技术性性大佬到达直播间间间与您互相探讨如何借助硬件配置配备灯源追踪技术性性,打造出下手机端影视制作制作级界面品质!

写作者 | 刘望舒

原文中承受权转截自后厂技术性性官 ID houchangcto

责编 | 胡巍巍

在shu.cn/framework/binder/3-addservice.html 文中中 我详尽详细介绍的是Native Binder中的系统软件手机软件服务的申请办理申请注册整个过程。

这一整个过程的重要是ServiceManager 而在Java Binder中 也是有一个ServiceManager 只不过是是这一ServiceManager是Java文本文档。
[标识:內容1]

即然要将系统软件手机软件服务申请办理申请注册到ServiceManager 那么务必选择一个系统软件手机软件服务为例子子 这儿以广泛的AMS为例子子。

将AMS申请办理申请注册到ServiceManager

在AMS的setSystemProcess方法中 会开启ServiceManager的addService方法 下列所显示信息。

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

    public void setSystemProcess() {        try {            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated  */ true,                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);//1           ....        } catch (PackageManager.NameNotFoundException e) {            throw new RuntimeException(                     Unable to find android system package , e);        }     ...    }

注释1处的Context.ACTIVITY_SERVICE的标值 activity 作用就是将AMS申请办理申请注册到ServiceManager中。随后来看ServiceManager的addService方法。
frameworks/base/core/java/android/os/ServiceManager.java

    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);        }    }

重要分析getIServiceManager方法返回的是什么 编号下列所显示信息。
frameworks/base/core/java/android/os/ServiceManager.java

   private static IServiceManager getIServiceManager() {        if (sServiceManager !  null) {            return sServiceManager;        }        sServiceManager   ServiceManagerNative                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));        return sServiceManager;    }

提及这儿 早就积累了许多个点务必分析 各有是

BinderInternal.getContextObject()

ServiceManagerNative.asInterface()

getIServiceManager().addService()

现如今大伙儿来每一个击破她们。

1.1 BinderInternal.getContextObject()

Binder.allowBlocking的作用是将BinderProxy的sWarnOnBlocking值置为false。

重要来分析BinderInternal.getContextObject()做了什么 这一方法是一个Native方法 找寻它相符合的涵数

frameworks/base/core/jni/android_util_Binder.cpp

static const JNINativeMethod gBinderInternalMethods[]   {    {  getContextObject ,  ()Landroid/os/IBinder; , (void*)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);//1    return javaObjectForIBinder(env, b);}

ProcessState::self()的作用 是创建ProcessState 注释1处最终返回的是BpBinder。

BpBinder是Native Binder中的Client端 这说明Java层的ServiceManager务必Native层的BpBinder。

但是这一BpBinder在Java层是无法马上运用 那么就务必传入javaObjectForIBinder涵数来做处理。

在其中部会创建一个BinderProxy总体目标 那般大伙儿得知 BinderInternal.getContextObject()最终得到的是BinderProxy。

BinderProxy是Java Binder的消费者端的寓意着。

务必注意的一点是 这一传入的BpBinder会存储到BinderProxy的组成员变量mObject中 过后会再一次谈及这一点。

1.2 ServiceManagerNative.asInterface()

说到asInterface方法 在Native Binder中也是有一个asInterface涵数 它的作用是用BpBinder做为关键主要参数创建BpServiceManager。

那么在Java Binder中的asInterface方法的作用也是什么

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);    }

根据1.1副标题 大伙儿得知obj的标值BinderProxy 那么asInterface方法的作用就是用BinderProxy作为关键主要参数创建ServiceManagerProxy。

BinderProxy和BpBinder各有在Jave Binder和Native Binder作为消费者端的寓意着 BpServiceManager依据BpBinder来进行通信、

一样的 ServiceManagerProxy也会将业务流程步骤的乞求交给BinderProxy来处理。分析到这儿 那么

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

可以掌握为

        sServiceManager   new ServiceManagerProxy BinderProxy);    }
1.3 getIServiceManager().addService()

根据1.2节的讲解 getIServiceManager()返回的是ServiceManagerProxy。

ServiceManagerProxy是ServiceManagerNative的内部类 它进行了IServiceManager插孔。

来查寻ServiceManagerProxy的addService方法

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

    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);//1        data.writeInt(allowIsolated ? 1 : 0);        data.writeInt(dumpPriority);        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//2        reply.recycle();        data.recycle();    }

注释1处的data.writeStrongBinder太重要 过后会进行分析。这儿又看到了Parcel 它是一总数据包裝器 将乞求数据信息信息内容加载到Parcel类型的总体目标data中。

依据注释1处的mRemote.transact消息推送出去 mRemote实际上是BinderProxy BinderProxy.transact是native涵数 进行的涵数下列所显示信息。

frameworks/base/core/jni/android_util_Binder.cpp    

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException{    if (dataObj   NULL) {        jniThrowNullPointerException(env, NULL);        return JNI_FALSE;    }    Parcel* data   parcelForJavaObject(env, dataObj);//1    if (data   NULL) {        return JNI_FALSE;    }    Parcel* reply   parcelForJavaObject(env, replyObj);//2    if (reply   NULL   replyObj !  NULL) {        return JNI_FALSE;    }    IBinder* target   getBPNativeData(env, obj)- mObject.get();//3    if (target   NULL) {        jniThrowException(env,  java/lang/IllegalStateException ,  Binder has been finalized!         return JNI_FALSE;    }   ...    status_t err   target- transact(code, *data, reply, flags);//4    return JNI_FALSE;}

注释1和注释2处 将Java层的Parcel总体目标变换变为Native层的Parcel总体目标。在1.1副标题中 大伙儿得知BpBinder会存储到BinderProxy的组成员变量mObject中 因此在注释3处 从BinderProxy的组成员变量mObject中得到BpBinder。

最终会在注释4处开启BpBinder的transact涵数 向Binder驱动器器消息推送数据信息信息内容 可以看出Java Binder是务必Native Binder可用的 最终的目的就是向Binder驱动器器消息推送和接纳数据信息信息内容。

引出来来JavaBBinder

随后转过头来分析1.3副标题遗留下下出去的data.writeStrongBinder(service) 编号下列所显示信息。

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

  public final void writeStrongBinder(IBinder ll) {        nativeWriteStrongBinder(mNativePtr, val);    }

nativeWriteStrongBinder是Native方法 进行的涵数为android_os_Parcel_writeStrongBinder 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));//1        if (err !  NO_ERROR) {            signalExceptionForError(env, clazz, err);        }    }}

随后查寻注释1处ibinderForJavaObject涵数 frameworks/base/core/jni/android_util_Binder.cpp

sp IBinder  ibinderForJavaObject(JNIEnv* env, jobject obj){    if (obj   NULL) return NULL;    if (env- IsInstanceOf(obj, gBinderOffsets.mClass)) {//1        JavaBBinderHolder* jbh   (JavaBBinderHolder*)            env- GetLongField(obj, gBinderOffsets.mObject);        return jbh- get(env, obj);//2    }    if (env- IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {        return getBPNativeData(env, obj)- mObject;    }    ALOGW( ibinderForJavaObject: %p is not a Binder object , obj);    return NULL;}

注释2处 倘若obj是Java层的BinderProxy类 则返回BpBinder。注释1处 倘若obj是Java层的Binder类 那么先得到JavaBBinderHolder总体目标 接着在注释2处开启JavaBBinderHolder的get涵数 编号下列所显示信息。frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder

class JavaBBinderHolder{public:    sp JavaBBinder  get(JNIEnv* env, jobject obj)    {        AutoMutex _l(mLock);        sp JavaBBinder  b   mBinder.promote();//1        if (b   NULL) {            //obj是一个Java层Binder总体目标            b   new JavaBBinder(env, obj);//2            mBinder              ALOGV( Creating JavaBinder %p (refs %p) for Object %p, weakCount %  PRId32  \n ,                 b.get(), b- getWeakRefs(), obj, b- getWeakRefs()- getWeakCount());        }        return b;    }    sp JavaBBinder  getExisting()    {        AutoMutex _l(mLock);        return mBinder.promote();    }private:    Mutex           mLock;    wp JavaBBinder  mBinder;};

组成员变量mBinder是wp JavaBBinder 类型的弱引进 在注释1处得到sp JavaBBinder 类型的强引进b 在注释2处创建JavaBBinder并赋值给b。那么 JavaBBinderHolder的get涵数返回的是JavaBBinder。

data.writeStrongBinder(service)在原文中中等水平水准价于

data.writeStrongBinder(new JavaBBinder(env Binder))。

提及这儿可以得知ServiceManager.addService()传入的实际上并不是AMS本身 仅仅JavaBBinder。

剖析JavaBBinder

随后来分析JavaBBinder 查寻它的构造涵数

frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder

class JavaBBinder : public BBinder{public:    JavaBBinder(JNIEnv* env, jobject /* Java Binder */ c)        : 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);    }...

可以发现JavaBBinder继承了BBinder 那么JavaBBinder的作用是什么呢

当Binder驱动器器得到消费者端的乞求 接着会将响应消息推送给JavaBBinder 这时候候会开启JavaBBinder的onTransact涵数 编号下列所显示信息 frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder

 virtual status_t onTransact(        uint32_t code, const Parcel  data, Parcel* reply, uint32_t flags   0)    {                                    JNIEnv* env   javavm_to_jnienv(mVM);        ALOGV( onTransact() on %p calling object %p in env %p vm %p\n , this, mObject, env, mVM);        IPCThreadState* thread_state   IPCThreadState::self();        const int32_t strict_policy_before   thread_state- getStrictModePolicy();        jboolean res   env- CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,            code, reinterpret_cast jlong ( data), reinterpret_cast jlong (reply), flags);//1        ...        return res !  JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;    }

在注释1处会开启Java层Binder的execTransact涵数

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

    private boolean execTransact(int code, long dataObj, long replyObj,            int flags) {...        try {            if (tracingEnabled) {                Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName()    :    code);            }            res   onTransact(code, data, reply, flags);//1        } catch (RemoteException|RuntimeException e) {           ...        }       ...        return res;    }

关键点是注释1处的onTransact涵数 AMS进行了onTransact涵数 从而开展业务流程步骤进行。

从这儿会出现看得到 JavaBBinder并没有进行什么业务流程步骤 当它接纳到乞求时 会开启Binder类的execTransact涵数 execTransact涵数内部又开启了onTransact涵数 系统软件手机软件服务会再次写过onTransact涵数来进行自身的业务流程步骤功效。

Java Binder架构

Binder架构下列图所显示信息。

Native Binder的一一部分在此前的文章内容內容早就讲过 这儿重要来说说Java Binder一一部分 从图可以见到

1.Binder是服务端的寓意着 JavaBBinder继承BBinder JavaBBinder依据mObject变量偏重Binder。

2.BinderProxy是消费者端的寓意着 ServiceManager的addService等方法会交到ServiceManagerProxy处理。

3.ServiceManagerProxy的组成员变量mRemote偏重BinderProxy总体目标 因而ServiceManagerProxy的addService等方法会交到BinderProxy来处理。

4.BinderProxy的组成员变量mObject偏重BpBinder总体目标 因此BinderProxy可以依据BpBinder和Binder驱动器器消息推送数据信息信息内容。

感谢
《深层次次掌握Android卷二》
《深层次次掌握Android卷三》
gityuan/2015/11/21/binder-framework/

【END】

热 文 推 荐 

开发设计设计方案者内行人动 在我国疫防开源系统系统软件最新项目踏入GitHub TOP榜


你点的每个在看 我都认真作为了钟爱


Wi-Fi 爆重大安全性性系统软件系统漏洞,Android、iOS、Windows 等所有无线网络互联网设备机器设备都不安全性性了 416685

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
无法在这个位置找到: ajaxfeedback.htm
栏目列表
推荐内容


扫描二维码分享到微信

在线咨询
联系电话

400-888-8866