Android Binder常用案例使用分析,跨进程通信aidl

这篇具有很好参考价值的文章主要介绍了Android Binder常用案例使用分析,跨进程通信aidl。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Android Binder常用案例使用分析

一.跨进程通信aidl

service组件的binderService获取binder通信。

servicemanager.getService方法获取相关服务。

本质上都是IBinder通信。

二.准备两个工程,客户端,服务端。

客户端:使用intent,启动服务端的service,使用binderservice,在onServiceConnected回调方法中获取服务端的实际binder对象。使用aidl中的接口调用服务端的方法即可。

服务端:定义接口aidl,使用Service组件,对aidl文件中的Stub抽象方法的实现,通过重写onBinder方法返回给客户端。

定义aidl并且编译

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

aidl会转换为对应的java文件

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

服务端实现onBinder方法,客户端绑定这个service的时候这个方法会被回调。
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

服务端实现aidl接口

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

客户端绑定回调,binderservice,

private void binderCustomService() {
        Intent intent = new Intent();
        intent.setAction("com.qfh.pay");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setPackage("com.example.service");
        CustomConnection customConnection = new CustomConnection();
        bindService(intent, customConnection, BIND_AUTO_CREATE);
    }

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

远端对象转为客户端本地接口对象使用

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

三. 测试

先运行服务端 再运行客户端,说明绑定成功

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

测试调用服务端接口,点击事件

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

点击

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder

服务端查看日志

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
完成跨进程通信。

补充1:java层aidl,binder

IHelloService

package com.testaidl;

interface IHelloService
{
	void sayhello();
	int sayhello_to(String name);
}

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
client
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
Android.bp,指定该模块编译方式,编译生成两个java模块一个客户端,一个服务端

java_library {
    name: "BinderClient",
    installable: true,
    srcs: [ "Client.java", 
            "HelloService.java", 
            "IHelloService.java" ],
}

java_library {
    name: "BinderServer",
    installable: true,
    srcs: [ "Server.java", 
            "HelloService.java", 
            "IHelloService.java" ],
}

Server
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
编译一下:

当前目录下执行mm命令进行单模块编译

编译成功
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
把这个jar包放入到模拟器中执行验证

Install: out/target/product/generic/system/framework/BinderServer.jar
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
链接jar包

export CLASSPATH=/data/local/tmp/BinderClient.jar :/data/local/tmp/BinderServer.jar

app进程启动服务端启动

app_process /data/local/tmp/ com.testaidl.Server &

客户端启动

app_process /data/local/tmp/ com.testaidl.Client

客户端log
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
服务端log
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
调用成功

Android binder的java层流程

源码路径

/home/android/aosp/frameworks/base/core/jni/AndroidRuntime.cpp

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),
    REG_JNI(register_android_util_Log),
    REG_JNI(register_android_util_MemoryIntArray),
    REG_JNI(register_android_util_PathParser),
    REG_JNI(register_android_util_StatsLog),
    REG_JNI(register_android_util_StatsLogInternal),
    REG_JNI(register_android_app_admin_SecurityLog),
    REG_JNI(register_android_content_AssetManager),
    REG_JNI(register_android_content_StringBlock),
    REG_JNI(register_android_content_XmlBlock),
    REG_JNI(register_android_content_res_ApkAssets),
    REG_JNI(register_android_text_AndroidCharacter),
    REG_JNI(register_android_text_Hyphenator),
    REG_JNI(register_android_view_InputDevice),
    REG_JNI(register_android_view_KeyCharacterMap),
    REG_JNI(register_android_os_Process),
    REG_JNI(register_android_os_SystemProperties),
    REG_JNI(register_android_os_Binder),
    REG_JNI(register_android_os_Parcel),
    REG_JNI(register_android_os_HidlSupport),
    REG_JNI(register_android_os_HwBinder),
    REG_JNI(register_android_os_HwBlob),
    REG_JNI(register_android_os_HwParcel),
    REG_JNI(register_android_os_HwRemoteBinder),
    REG_JNI(register_android_os_NativeHandle),
    REG_JNI(register_android_os_VintfObject),
    REG_JNI(register_android_os_VintfRuntimeInfo),
    REG_JNI(register_android_graphics_Canvas),
    // This needs to be before register_android_graphics_Graphics, or the latter
    // will not be able to find the jmethodID for ColorSpace.get().
    REG_JNI(register_android_graphics_ColorSpace),
    REG_JNI(register_android_graphics_Graphics),
    REG_JNI(register_android_view_DisplayEventReceiver),
    REG_JNI(register_android_view_RenderNode),
    REG_JNI(register_android_view_RenderNodeAnimator),
    REG_JNI(register_android_view_DisplayListCanvas),
    REG_JNI(register_android_view_InputApplicationHandle),
    REG_JNI(register_android_view_InputWindowHandle),
    REG_JNI(register_android_view_TextureLayer),
    REG_JNI(register_android_view_ThreadedRenderer),
    REG_JNI(register_android_view_Surface),
    REG_JNI(register_android_view_SurfaceControl),
    REG_JNI(register_android_view_SurfaceSession),
    REG_JNI(register_android_view_CompositionSamplingListener),
    REG_JNI(register_android_view_TextureView),
    REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
    REG_JNI(register_com_google_android_gles_jni_EGLImpl),
    REG_JNI(register_com_google_android_gles_jni_GLImpl),
    REG_JNI(register_android_opengl_jni_EGL14),
    REG_JNI(register_android_opengl_jni_EGL15),
    REG_JNI(register_android_opengl_jni_EGLExt),
    REG_JNI(register_android_opengl_jni_GLES10),
    REG_JNI(register_android_opengl_jni_GLES10Ext),
    REG_JNI(register_android_opengl_jni_GLES11),
    REG_JNI(register_android_opengl_jni_GLES11Ext),
    REG_JNI(register_android_opengl_jni_GLES20),
    REG_JNI(register_android_opengl_jni_GLES30),
    REG_JNI(register_android_opengl_jni_GLES31),
    REG_JNI(register_android_opengl_jni_GLES31Ext),
    REG_JNI(register_android_opengl_jni_GLES32),

    REG_JNI(register_android_graphics_Bitmap),
    REG_JNI(register_android_graphics_BitmapFactory),
    REG_JNI(register_android_graphics_BitmapRegionDecoder),
    REG_JNI(register_android_graphics_ByteBufferStreamAdaptor),
    REG_JNI(register_android_graphics_Camera),
    REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
    REG_JNI(register_android_graphics_CanvasProperty),
    REG_JNI(register_android_graphics_ColorFilter),
    REG_JNI(register_android_graphics_DrawFilter),
    REG_JNI(register_android_graphics_FontFamily),
    REG_JNI(register_android_graphics_GraphicBuffer),
    REG_JNI(register_android_graphics_ImageDecoder),
    REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable),
    REG_JNI(register_android_graphics_Interpolator),
    REG_JNI(register_android_graphics_MaskFilter),
    REG_JNI(register_android_graphics_Matrix),
    REG_JNI(register_android_graphics_Movie),
    REG_JNI(register_android_graphics_NinePatch),
    REG_JNI(register_android_graphics_Paint),
    REG_JNI(register_android_graphics_Path),
    REG_JNI(register_android_graphics_PathMeasure),
    REG_JNI(register_android_graphics_PathEffect),
    REG_JNI(register_android_graphics_Picture),
    REG_JNI(register_android_graphics_Region),
    REG_JNI(register_android_graphics_Shader),
    REG_JNI(register_android_graphics_SurfaceTexture),
    REG_JNI(register_android_graphics_Typeface),
    REG_JNI(register_android_graphics_YuvImage),
    REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable),
    REG_JNI(register_android_graphics_drawable_VectorDrawable),
    REG_JNI(register_android_graphics_fonts_Font),
    REG_JNI(register_android_graphics_fonts_FontFamily),
    REG_JNI(register_android_graphics_pdf_PdfDocument),
    REG_JNI(register_android_graphics_pdf_PdfEditor),
    REG_JNI(register_android_graphics_pdf_PdfRenderer),
    REG_JNI(register_android_graphics_text_MeasuredText),
    REG_JNI(register_android_graphics_text_LineBreaker),

    REG_JNI(register_android_database_CursorWindow),
    REG_JNI(register_android_database_SQLiteConnection),
    REG_JNI(register_android_database_SQLiteGlobal),
    REG_JNI(register_android_database_SQLiteDebug),
    REG_JNI(register_android_os_Debug),
    REG_JNI(register_android_os_FileObserver),
    REG_JNI(register_android_os_GraphicsEnvironment),
    REG_JNI(register_android_os_MessageQueue),
    REG_JNI(register_android_os_SELinux),
    REG_JNI(register_android_os_Trace),
    REG_JNI(register_android_os_UEventObserver),
    REG_JNI(register_android_net_LocalSocketImpl),
    REG_JNI(register_android_net_NetworkUtils),
    REG_JNI(register_android_os_MemoryFile),
    REG_JNI(register_android_os_SharedMemory),
    REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
    REG_JNI(register_com_android_internal_os_Zygote),
    REG_JNI(register_com_android_internal_os_ZygoteInit),
    REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
    REG_JNI(register_android_hardware_Camera),
    REG_JNI(register_android_hardware_camera2_CameraMetadata),
    REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice),
    REG_JNI(register_android_hardware_camera2_legacy_PerfMeasurement),
    REG_JNI(register_android_hardware_camera2_DngCreator),
    REG_JNI(register_android_hardware_HardwareBuffer),
    REG_JNI(register_android_hardware_SensorManager),
    REG_JNI(register_android_hardware_SerialPort),
    REG_JNI(register_android_hardware_SoundTrigger),
    REG_JNI(register_android_hardware_UsbDevice),
    REG_JNI(register_android_hardware_UsbDeviceConnection),
    REG_JNI(register_android_hardware_UsbRequest),
    REG_JNI(register_android_hardware_location_ActivityRecognitionHardware),
    REG_JNI(register_android_media_AudioEffectDescriptor),
    REG_JNI(register_android_media_AudioSystem),
    REG_JNI(register_android_media_AudioRecord),
    REG_JNI(register_android_media_AudioTrack),
    REG_JNI(register_android_media_AudioAttributes),
    REG_JNI(register_android_media_AudioProductStrategies),
    REG_JNI(register_android_media_AudioVolumeGroups),
    REG_JNI(register_android_media_AudioVolumeGroupChangeHandler),
    REG_JNI(register_android_media_JetPlayer),
    REG_JNI(register_android_media_MicrophoneInfo),
    REG_JNI(register_android_media_RemoteDisplay),
    REG_JNI(register_android_media_ToneGenerator),
    REG_JNI(register_android_media_midi),

    REG_JNI(register_android_opengl_classes),
    REG_JNI(register_android_server_NetworkManagementSocketTagger),
    REG_JNI(register_android_ddm_DdmHandleNativeHeap),
    REG_JNI(register_android_backup_BackupDataInput),
    REG_JNI(register_android_backup_BackupDataOutput),
    REG_JNI(register_android_backup_FileBackupHelperBase),
    REG_JNI(register_android_backup_BackupHelperDispatcher),
    REG_JNI(register_android_app_backup_FullBackup),
    REG_JNI(register_android_app_Activity),
    REG_JNI(register_android_app_ActivityThread),
    REG_JNI(register_android_app_NativeActivity),
    REG_JNI(register_android_util_jar_StrictJarFile),
    REG_JNI(register_android_view_InputChannel),
    REG_JNI(register_android_view_InputEventReceiver),
    REG_JNI(register_android_view_InputEventSender),
    REG_JNI(register_android_view_InputQueue),
    REG_JNI(register_android_view_KeyEvent),
    REG_JNI(register_android_view_MotionEvent),
    REG_JNI(register_android_view_PointerIcon),
    REG_JNI(register_android_view_VelocityTracker),

    REG_JNI(register_android_content_res_ObbScanner),
    REG_JNI(register_android_content_res_Configuration),

    REG_JNI(register_android_animation_PropertyValuesHolder),
    REG_JNI(register_android_security_Scrypt),
    REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
    REG_JNI(register_com_android_internal_os_AtomicDirectory),
    REG_JNI(register_com_android_internal_os_FuseAppLoop),
};

Android的zygote进程启动的时候会调用jni的注册方法,注册一系列的jni函数

/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    ATRACE_NAME("RegisterAndroidNatives");
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    ALOGV("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}

跟binder相关的是下面这几个,都是注册跟他们相关的binder jni底层函数

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;
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
        }

分析流程,register_jni_procs调用这个方法注册jni函数

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    for (size_t i = 0; i < count; i++) {
        if (array[i].mProc(env) < 0) {
#ifndef NDEBUG
            ALOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
            return -1;
        }
    }
    return 0;
}

gRegJNI是一个数组指针,然后进入这个方法之后就会回调到REG_JNI(register_android_os_Binder),

然后就会执行register_android_os_Binder这个里面的方法。

static int int_register_android_os_Binder(JNIEnv* env)
{	
    //kBinderPathName,"android/os/Binder"
    jclass clazz = FindClassOrDie(env, kBinderPathName);

    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
    gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
        "()Ljava/lang/String;");
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
	//注册jni函数的一个方法
    return RegisterMethodsOrDie(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}
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 }
};

jclass clazz = FindClassOrDie(env, kBinderPathName);首先先获取到Binder.java类的jclass

获取到的数据都会保存在这个结构体里面

static struct bindernative_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mExecTransact;
    jmethodID mGetInterfaceDescriptor;

    // Object state.
    jfieldID mObject;

} gBinderOffsets;

Android的服务注册过程(java层)

在我们自己的代码中都是//添加服务
ServiceManager.addService(“hello”, new HelloService());这样去添加一个服务

第一个参数是服务的名字,第二个参数是继承自Binder的一个实现类

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

当我们的自己的实现的aidl文件的对象创建的时候,会调用Binder的构造方法

public Binder(@Nullable String descriptor)  {
    //getNativeBBinderHolder是一个natve函数
        mObject = getNativeBBinderHolder();
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);

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

mObject = getNativeBBinderHolder();进入这个方法,mObject是jni函数返回的一个对象指针,

路径

/home/android/aosp/frameworks/base/core/jni/android_util_Binder.cpp

static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
{
    //生成一个对象,并且把这个对象的指针返回* jbh成一个句柄long型
    JavaBBinderHolder* jbh = new JavaBBinderHolder();
    return (jlong) jbh;
}

看一下JavaBBinderHolder类


class JavaBBinderHolder
{
public:
    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    {
        AutoMutex _l(mLock);
    
        sp<JavaBBinder> b = mBinder.promote();
        if (b == NULL) {
            //第一次进来new一个新对象
            b = new JavaBBinder(env, obj);
            mBinder = b;
            ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
        }

        return b;
    }

    sp<JavaBBinder> getExisting()
    {
        AutoMutex _l(mLock);
        return mBinder.promote();
    }

private:
    Mutex           mLock;
    wp<JavaBBinder> mBinder;
};

wp mBinder;这是一个弱引用对应JavaBBinder实体类

最终就是把这个JavaBBinder的指针,也就是这个对象的地址通过一个long型返回给java层,这样java层就能持有这个对象了

最终保存在mObject中

所以我们自定义的service就可以访问这个成员,因为他继承自binder

所以我们的自定义服务就可以通过这个mObject对象所指向的地址去访问JavaBBinderHolder(native层)

addService分析

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
有三个重载函数

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) {
        addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
    }
	//最终会调用这个
    @UnsupportedAppUsage
    public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            //getIServiceManager返回ServiceManager的一个代理类,通过代理类的addService发起远程调用
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

源码路径

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

    @UnsupportedAppUsage
    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

BinderInternal.getContextObject()构建一个代理类对象binder的去构造一个ServiceManager的代理类对象

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

@UnsupportedAppUsage
    public static final native IBinder getContextObject();

又是一个jni方法

frameworks/base/core/jni/android_util_Binder.cpp


static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{	
    //构造BpBinder对象,传一个0进去
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
handle就是我们传进来的0
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
最终返回的对象传给下面这个函数


static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{	
    //构造BpBinder对象,传一个0进去
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}

看下javaObjectForIBinder,val就是上面的BpBinder

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;
    //mObject指向BpBinder
    nativeData->mObject = val;
	//CallStaticObjectMethod调用java层的静态方法mGetInstance
    //获取BinderProxy对象
    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;
}

mGetInstance,这个类主要是获取BinderProxy对象

    private static BinderProxy getInstance(long nativeData, long iBinder) {
        BinderProxy result;
        synchronized (sProxyMap) {
            try {
                //map缓存对象
                result = sProxyMap.get(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;
    }

最终回到我们这里asInterface里面最终传递的就是BinderProxy对象,handler的句柄就是0

@UnsupportedAppUsage
private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }

    // Find the service manager
    sServiceManager = ServiceManagerNative
            .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

接下来我们看下这个asInterface

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

  @UnsupportedAppUsage
    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
		//ServiceManagerProxy对象创建
        return new ServiceManagerProxy(obj);
    }
@UnsupportedAppUsage
private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }

    // Find the service manager
    //ServiceManagerProxy最终拿到这个对象
    sServiceManager = ServiceManagerNative
            .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

queryLocalInterface函数
Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
最终我们会调用ServiceManagerProxy中的addService

/home/android/aosp/frameworks/base/core/java/android/os/ServiceManagerNative.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);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        data.writeInt(dumpPriority);
        //发起远程调用
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder
这个mRemote就是前面的BinderProxy对象

mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);

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

        if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
            // For now, avoid spamming the log by disabling after we've logged
            // about this interface at least once
            mWarnOnBlocking = false;
            Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
                    new Throwable());
        }

        final boolean tracingEnabled = Binder.isTracingEnabled();
        if (tracingEnabled) {
            final Throwable tr = new Throwable();
            Binder.getTransactionTracker().addTrace(tr);
            StackTraceElement stackTraceElement = tr.getStackTrace()[1];
            Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
                    stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
        }

        // Make sure the listener won't change while processing a transaction.
        final Binder.ProxyTransactListener transactListener = sTransactListener;
        Object session = null;

        if (transactListener != null) {
            final int origWorkSourceUid = Binder.getCallingWorkSourceUid();
            session = transactListener.onTransactStarted(this, code);

            // Allow the listener to update the work source uid. We need to update the request
            // header if the uid is updated.
            final int updatedWorkSourceUid = Binder.getCallingWorkSourceUid();
            if (origWorkSourceUid != updatedWorkSourceUid) {
                data.replaceCallingWorkSourceUid(updatedWorkSourceUid);
            }
        }

        try {
            //
            return transactNative(code, data, reply, flags);
        } finally {
            if (transactListener != null) {
                transactListener.onTransactEnded(session);
            }

            if (tracingEnabled) {
                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
            }
        }
    }

关注这个方法 return transactNative(code, data, reply, flags);他是个jni方法

obj代表BinderProxy

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;
    }
	//获取BpBinder
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }

    ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
            target, obj, code);


    bool time_binder_calls;
    int64_t start_millis;
    if (kEnableBinderSample) {
        // Only log the binder call duration for things on the Java-level main thread.
        // But if we don't
        time_binder_calls = should_time_binder_calls();

        if (time_binder_calls) {
            start_millis = uptimeMillis();
        }
    }
	//最终在这里使用BpBinder发起远程调用
    //printf("Transact from Java code to %p sending: ", target); data->print();
    status_t err = target->transact(code, *data, reply, flags);
    //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();

    if (kEnableBinderSample) {
        if (time_binder_calls) {
            conditionally_log_binder_call(start_millis, target, code);
        }
    }

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

Android Binder常用案例使用分析,跨进程通信aidl,Android framework,android,binder文章来源地址https://www.toymoban.com/news/detail-724689.html

到了这里,关于Android Binder常用案例使用分析,跨进程通信aidl的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Binder通信原理(三):service注册

    源码基于: Android R 上一文中详细分析了 servicemanger 的启动流程 ,我们知道 servicemanager 作为 binder 机制中的一个特殊service,利用service map管理所有service,也是所有binder 通信的入口。 本文着重分析 service 的注册流程,下一文着重分析service 的获取流程。 Binder 中每个进程都会有

    2024年02月11日
    浏览(40)
  • Android Binder通信原理(二):servicemanager启动

    源码基于: Android R 下图是android 8.0 之前binder 的软件框架,依赖的驱动设备是/dev/binder,binder机制的四要素分别是client、server、servicemanager和binder驱动。 对于android 8.0后的binder 和vndbinder依然同这个框架,只不过驱动的设备多加/dev/vndbinder 这篇主要分析servicemanger的流程,hwserv

    2024年02月11日
    浏览(41)
  • Android Binder通信原理(七):java 下的C-S

    源码基于: Android R 在之前的几篇博文中,对Android binder 的通信原理进行的深入的剖析,这些博文包括: binder 简介 、 servicemanager启动 、 service注册 、 service获取 、 Java 端的service 注册和获 取。 在前一文中,通过实例,详细地说明了 native 下 的C-S 通信原理 。 本文在之前的基

    2024年02月11日
    浏览(39)
  • Android Binder通信原理(五):Java 端的service 注册和获取

    源码基于: Android R 在阐述相关的知识点,先整理个框架图,后面带着框架图来分析过程: Java 端对于binder 使用大致分为: Java client Java service Java client native service Java 端service 的注册使用 ServiceManager.addService() Java 端service 的获取使用 ServiceManager.getService() 入口都是通过 Servic

    2024年02月11日
    浏览(41)
  • BpBinder与PPBinder调用过程——Android开发Binder IPC通信技术

    在Android系统中,进程间通信(IPC)是一个非常重要的话题。Android系统通过Binder IPC机制实现进程间通信,而Binder IPC通信技术则是Android系统中最为重要的进程间通信技术之一。本文将介绍Binder IPC通信技术的原理,并详细解析BpBinder与PPBinder调用过程的使用以及注意事项。 Bind

    2024年02月13日
    浏览(36)
  • 【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

    Android 中的 Binder 是一个进程间通信机制,它允许不同进程之间相互调用方法和传递数据。Binder 主要用于实现系统服务和应用程序之间的通信,以及实现 IPC(Inter-Process Communication,进程间通信)。 Binder 的核心是 Binder 驱动程序,它负责管理不同进程之间的通信。每个进程都可

    2024年02月07日
    浏览(40)
  • [DEMO] Android Binder 的使用

    The Android binderfs Filesystem — The Linux Kernel documentation Android Binder 是一种 IPC 机制,IPC 键值/标识 是一个字符串,收发双方通过 键值/标识 建立通讯路径。 Binder 是通过模板类实现的,因此使用起来并不是那么简明通俗,如果没有demo可以参考的话是需要琢磨好一阵子。 class IInt

    2024年02月13日
    浏览(36)
  • macOS跨进程通信: TCP Socket 创建实例

    macOS跨进程通信: TCP Socket 创建实例 Socket 是 网络传输的抽象概念。 一般我们常用的有 Tcp Socket 和 UDP Scoket , 和类Unix 系统(包括Mac)独有的 Unix Domain Socket (UDS)。 Tcp Socket 能够跨电脑进行通信,即使是在同一个电脑下的多进程间通信,也会通过网卡进行数据传输,如果本地

    2024年01月24日
    浏览(40)
  • 鸿蒙OS跨进程IPC与RPC通信

    基本概念 IPC(Inter-Process Communication)与RPC(Remote Procedure Call)用于实现跨进程通信,不同的是前者使用Binder驱动,用于设备内的跨进程通信,后者使用软总线驱动,用于跨设备跨进程通信。需要跨进程通信的原因是因为每个进程都有自己独立的资源和内存空间,其他进程不能

    2024年02月22日
    浏览(31)
  • 跨进程通信设计:Qt 进程间通讯类全面解析

    进程间通信(Interprocess Communication,简称 IPC)是现代软件开发中不可或缺的一部分。在许多应用场景中,多个进程需要共享数据、协同工作,或在不同进程间传递消息。IPC 技术允许这些进程安全、高效地通信,从而实现复杂的功能和任务。 Qt 提供了一系列进程间通信类,以

    2023年04月18日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包