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/zh-hk/n/372318.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
BZWMW的頭像BZWMW
上一篇 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

發表回復

登錄後才能評論