Android Binder机制详解

一、Binder机制概述

Binder是一种进程间通信机制,它是Android系统中非常重要的一部分。在Android系统中,应用程序需要和设备驱动程序、系统服务等进程进行通信,这就需要使用到Binder机制。

Binder机制是基于线程的进程间通信机制。Android系统中的每个进程都有一个Binder驱动,它负责创建Binder对象并维护Binder对象之间的连接。通过Binder机制,不同的进程可以共享数据,实现共享内存,同时也可以进行RPC(远程过程调用)。

Binder驱动会在内核层面为每个Binder对象分配一个唯一的标识符——Binder物理地址(Binder node)。

二、Binder机制的实现

1、Binder对象

Binder对象是Android系统中的核心对象,它是进程间通信的基础。在Binder机制中,每个进程通过创建接口类(Binder类)实现一个Binder对象,在进程间通信时将Binder对象传递给其他进程。

在Java层,Binder类是AIDL(Android Interface Definition Language)文件编译后生成的Java类,所有的Binder接口定义都必须使用AIDL文件来定义。

// IMyAidlInterface.aidl文件
interface IMyAidlInterface {
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString);
}

// IMyAidlInterface.java文件
public interface IMyAidlInterface extends android.os.IInterface {
...
}

在C++层,Binder对象则是继承自BBinder的类,BBinder类实现了Binder对象的基本功能。

// IBinder.h文件
class IBinder : public IInterface {
public:
    DECLARE_META_INTERFACE(Binder);

    virtual status_t    transact(   uint32_t        code,
                                    const Parcel&   data,
                                    Parcel*         reply,
                                    uint32_t        flags = 0) = 0;
...
};

// BBinder.h文件
class BBinder : public BnBinder {
public:
    virtual status_t    onTransact( uint32_t        code,
                                    const Parcel&   data,
                                    Parcel*         reply,
                                    uint32_t        flags = 0);
...
};

2、Binder驱动

Binder驱动是Android系统中专门用来处理Binder对象的进程,它主要负责的是Binder对象之间的连接、维护和转发等工作。

Binder驱动会为每个进程提供一个Binder设备文件(/dev/binder),每个进程都必须通过/dev/binder文件与Binder驱动通信,进行Binder对象的创建、连接和通信等操作。

3、Binder节点

当进程创建一个Binder对象时,Binder驱动会为该Binder对象分配一个唯一的标识符——Binder节点(Binder node),用于区分不同的Binder对象。

Binder节点是唯一的长整型标识符,其内部存储表示为一个指针。在Java层,Binder节点实际上是Java对象的引用。

在C++层,Binder节点指向的是Binder对象的头部,包括一个指向Binder对象的引用计数、一个指向Binder对象的类型所在的引用计数表的指针,以及类型ID和事务ID。

三、Binder机制的使用

1、创建和传递Binder对象

在创建Binder对象和将Binder对象传递给其他进程时,需要使用相应的API接口来完成。

在Java层,创建Binder对象需要使用Binder类,将Binder对象传递给其他进程需要使用IBinder接口。

// 创建Binder对象
private final IBinder mBinder = new MyBinder();

// 将Binder对象传递给其他进程
Intent intent = new Intent(this, MyService.class);
intent.putExtra("binder", mBinder);
startService(intent);

在C++层,创建Binder对象需要使用BnXXX或BpXXX类,将Binder对象传递给其他进程需要使用IBinder接口。

// 创建Binder对象
class MyBinder : public BnMyInterface {
...
};

// 将Binder对象传递给其他进程
sp sm = defaultServiceManager();
sm->addService(String16("my_service"), new MyService());

2、Binder对象的连接和阻塞

在进程间通信过程中,连接相关的操作都是在Binder驱动中完成的。

当一个进程调用Binder对象的transact方法来与另一个进程进行通信时,如果此时另一个进程还没有准备好接受数据,那么当前进程就会被阻塞,直到另一个进程准备好接受数据。

在Java层,使用Binder类连接和阻塞Binder对象需要使用while循环,不断调用transact方法,直到连接成功。

// 连接Binder对象
mService = IMyInterface.Stub.asInterface(service);

// 阻塞Binder对象
while (mService == null) {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    mService = IMyInterface.Stub.asInterface(service);
}

在C++层,使用IBinder接口连接和阻塞Binder对象需要使用IPCThreadState类,IPCThreadState类提供了很多阻塞式的连接和传输方法。

// 连接Binder对象
sp binder = defaultServiceManager()->getService(String16("my_service"));

// 阻塞Binder对象
if (binder == nullptr) {
    binder = IPCThreadState::self()->waitForService(String16("my_service"));
}

3、Binder对象的传输和接收

Binder对象的传输和接收都是通过Binder驱动来实现的,具体的传输和接收过程由驱动进行管理。

在Java层,向Binder对象发送数据需要创建Parcel对象,将需要传输的数据打包到Parcel中,然后通过transact方法将Parcel传递给另一个进程。接收数据时,需要在onTransact方法中解析Parcel对象,获取传输过来的数据。

// 发送数据
Parcel data = Parcel.obtain();
data.writeInt(123);
data.writeLong(456);
service.transact(1, data, null, 0);

// 接收数据
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    switch (code) {
        case 1: {
            int arg1 = data.readInt();
            long arg2 = data.readLong();

            Log.d(TAG, "arg1: " + arg1 + ", arg2: " + arg2);
            break;
        }
    }

    return super.onTransact(code, data, reply, flags);
}

在C++层,发送和接收数据需要使用Parcel类,具体的过程与Java层类似。Parcel类提供了读写基本类型和创建自定义数据结构的方法,可以方便地进行数据的传输和接收。

// 发送数据
Parcel data;
data.writeInt32(123);
data.writeInt64(456);
binder->transact(1, data, &reply);

// 接收数据
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    switch (code) {
        case 1: {
            int32_t arg1 = data.readInt32();
            int64_t arg2 = data.readInt64();

            ALOGD("arg1: %d, arg2: %lld", arg1, arg2);
            break;
        }
    }

    return BBinder::onTransact(code, data, reply, flags);
}

四、总结

本文介绍了Android系统中非常重要的一部分——Binder机制。Binder机制是进程间通信的核心机制,它可以实现进程间数据的共享和RPC等功能。我们从Binder机制的概述、实现和使用三个方面对Binder机制进行了详细阐述,希望能够帮助读者更好地理解和使用Binder机制。

原创文章,作者:BZWMW,如若转载,请注明出处:https://www.506064.com/n/372318.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
BZWMWBZWMW
上一篇 2025-04-24 06:40
下一篇 2025-04-24 06:40

相关推荐

  • Spring S_CSRF防护机制实现及应用

    Spring S_CSRF防护机制是Spring Security框架提供的一个针对跨站请求伪造攻击(CSRF)的保护机制。本文将从以下几个方面详细介绍Spring S_CSRF防…

    编程 2025-04-28
  • Android ViewPager和ScrollView滑动冲突问题

    Android开发中,ViewPager和ScrollView是两个常用的控件。但是当它们同时使用时,可能会发生滑动冲突的问题。本文将从多个方面介绍解决Android ViewPa…

    编程 2025-04-28
  • Android如何点击其他区域收起软键盘

    在Android应用中,当输入框获取焦点弹出软键盘后,我们希望能够点击其他区域使软键盘消失,以提升用户体验。本篇文章将说明如何实现这一功能。 一、获取焦点并显示软键盘 在Andro…

    编程 2025-04-28
  • Python的垃圾回收机制

    本文将对Python的垃圾回收机制进行详细阐述,着重介绍它的基本原理和实现方式。此外,我们还将介绍常见的问题及解决方法,并给出相应的代码示例。 一、Python的垃圾回收概述 垃圾…

    编程 2025-04-27
  • Android Studio HUD 实现指南

    本文将会以实例来详细阐述如何在 Android Studio 中使用 HUD 功能实现菊花等待指示器的效果。 一、引入依赖库 首先,我们需要在 build.gradle 文件中引入…

    编程 2025-04-27
  • 机制与策略分离

    了解机制与策略分离的解决方法与优势 一、概述 机制与策略分离是一种软件设计理念,它将复杂的系统、组件等模块化,通过分离机制与策略,把模块实现的方式与具体使用方式分开。 机制是实现某…

    编程 2025-04-27
  • Android和Vue3混合开发方案

    本文将介绍如何将Android和Vue3结合起来进行混合开发,以及其中的优势和注意事项。 一、环境搭建 在进行混合开发之前,需要搭建好相应的开发环境。首先需要安装 Android …

    编程 2025-04-27
  • Android Java Utils 可以如何提高你的开发效率

    Android Java Utils 是一款提供了一系列方便实用的工具类的 Java 库,可以帮助开发者更加高效地进行 Android 开发,提高开发效率。本文将从以下几个方面对 …

    编程 2025-04-27
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25

发表回复

登录后才能评论