Android Binder實現示例(C/C++層)
本文參考前輩文章,記錄自己學習瞭解Binder的一個過程;以一個例子來看下Binder的一個實現過程。
Java層的實現可參看另一篇文章:Android系統服務編寫例項-Binder(Java層AIDL)
一、示例
C層Binder開發的架構圖
BinderTest
├── client//客戶端目錄
│ ├── Android.mk
│ ├── BpBinderTest.cpp
│ ├── BpBinderTest.h
│ └── main_client.cpp
├── common//通用介面
│ ├── IBinderTest.cpp
│ └── IBinderTest.h
└── server//服務端目錄
├── Android.mk
├── BinderTestService.cpp
├── BinderTestService.h
├── BnBinderTest.cpp
├── BnBinderTest.h
└── main_server.cpp
1、common分析
1.1 IBinderTest.h
#ifndef ANDROID_IHELLOWORLDSERVICE_H
#define ANDROID_IHELLOWORLDSERVICE_H
#include <binder/IInterface.h>
namespace android{
enum {
HW_HELLOWORLD2=IBinder::FIRST_CALL_TRANSACTION,
};
class IBinderTest: public IInterface//繼承自IInterface,用於提供C/S的統一介面
{
public:
DECLARE_META_INTERFACE(BinderTest);//這是一個巨集定義
virtual status_t binderTest(const char *str)=0;//一個簡單的測試函式
};
};
#endif
2、Server分析
2.1 BnBinderTest.h
#include "../common/IBinderTest.h"
namespace android{
class BnBinderTest: public BnInterface<IBinderTest>//繼承BnInterface
{
public:
//onTransact此函式在BnBinderTest.cpp中具體實現,它用於處理來自client端對應的請求
virtual status_t onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags =0);
};
};
2.2 BnBinderTest.cpp
#include <binder/Parcel.h>
#include "BnBinderTest.h"
namespace android {
//對BnBinderTest的onTransact實現,還會在後面其子類BnBinderTestService中重寫此方法
status_t BnBinderTest::onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags)
{
switch(code){
case HW_HELLOWORLD2:{//在IBinderTest.h介面中定義
CHECK_INTERFACE(IBinderTest,data,reply);//檢查介面
const char *str;
str = data.readCString();
reply->writeInt32(binderTest(str));//這裡呼叫執行我們定義的binderTest函式
return NO_ERROR;
}break;
default:
return BBinder::onTransact(code,data,reply,flags);
}
}
};
2.3 BinderTestService.h
#include<binder/Parcel.h>
#include"BnBinderTest.h"
#include<utils/Log.h>
namespace android {
class BinderTestService: public BnBinderTest//繼承
{
public:
static void instantiate();
virtual status_t binderTest(const char *str);//實現介面IBinderTest的函式,這些是我們自己需要實現的一些功能函式
virtual status_t onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags = 0);
private:
BinderTestService();
virtual ~BinderTestService();
};
};
2.4 BinderTestService.cpp
#include<binder/IServiceManager.h>
#include<binder/IPCThreadState.h>
#include<utils/Log.h>
#include"BinderTestService.h"
namespace android{
//這個函式是將自己註冊進servicemanager
void BinderTestService::instantiate(){
defaultServiceManager()->addService(String16("android.test.IBinderTest"),new BinderTestService);
}
//這個函式是我們要實現的功能,其在BnBinderTest的onTransact中被呼叫
status_t BinderTestService::binderTest(const char *str)
{
ALOGI("receive string:%s\n",str);
printf("print string:%s\n",str);//簡單的列印一個字串
return NO_ERROR;
}
BinderTestService::BinderTestService()
{
ALOGI("BinderTestService is created");
printf("BinderTestService is created\n");
}
BinderTestService::~BinderTestService()
{
ALOGI("BinderTestService is destroyed");
printf("BinderTestService is destroyed\n");
}
status_t BinderTestService::onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags)
{
ALOGI("BinderTestService onTransact");
printf("BinderTestService onTransact\n");
return BnBinderTest::onTransact(code,data,reply,flags);//呼叫父類的函式
}
};
2.5 main_server.cpp(server端的啟動程式)
#define LOG_TAG "main_server"
#include<binder/IPCThreadState.h>
#include<binder/ProcessState.h>
#include<binder/IServiceManager.h>
#include<utils/Log.h>
#include"BinderTestService.h"
using namespace android;
int main(int argc,char *argv[]){
BinderTestService::instantiate();//註冊進servicemanager中
//開啟執行緒池,接收處理Client傳送的程式間通訊請求
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
2.6 Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=\
../common/IBinderTest.cpp\
BnBinderTest.cpp\
BinderTestService.cpp\
main_server.cpp
LOCAL_SHARED_LIBRARIES:=\
libcutils\
libutils\
libbinder
LOCAL_MODULE:= main_server
include $(BUILD_EXECUTABLE)
3、Client分析
3.1 BpBinderTest.h
#include "../common/IBinderTest.h"
namespace android{
class BpBinderTest: public BpInterface<IBinderTest>
{
public:
BpBinderTest(const sp<IBinder>& impl);
virtual status_t binderTest(const char *str);
};
};
3.2 BpBinderTest.cpp
#include <binder/Parcel.h>
#include "BpBinderTest.h"
#include <utils/Log.h>
namespace android{
status_t BpBinderTest::binderTest(const char *str)
{
Parcel data,reply;
data.writeInterfaceToken(IBinderTest::getInterfaceDescriptor());
data.writeCString(str);
//通過code呼叫遠端BinderTest方法,傳遞data
status_t status = remote()->transact(HW_HELLOWORLD2,data,&reply);
if(status != NO_ERROR){
ALOGE("BinderTest error: %s",strerror(-status));
}else{
status = reply.readInt32();
}
return status;
}
BpBinderTest::BpBinderTest(const sp<IBinder>& impl): BpInterface<IBinderTest>(impl){}
};
3.3 main_client.cpp
#define LOG_TAG "main_helloworldclient"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include "../common/IBinderTest.h"
using namespace android;
int main(int argc,char *argv[])
{
ALOGI("HelloWorldSevice client is starting now");
//獲取ServiceManager,從而能得到遠端IBinder,實現通訊
sp<IServiceManager> sm =defaultServiceManager();
sp<IBinder> b;
sp<IBinderTest> sBinderTest;
do{
b=sm->getService(String16("android.test.IBinderTest"));
if(b != 0){
break;
}
ALOGI("BinderTest is not working,waiting...");
printf("BinderTest is not working,waiting...\n");
usleep(500000);
}while(true);
sBinderTest = interface_cast<IBinderTest>(b);
sBinderTest->binderTest("Hello,World!\n");
return 0;
}
3.4 Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=\
../common/IBinderTest.cpp\
BpBinderTest.cpp\
main_client.cpp
LOCAL_SHARED_LIBRARIES:=\
libcutils\
libutils\
libbinder
LOCAL_MODULE:= main_client
include $(BUILD_EXECUTABLE)
DEMO下載:https://download.csdn.net/download/qq_25269161/10918706
如下參考
https://www.cnblogs.com/samchen2009/p/3316001.html
歸納一下,
- BBinder 實現了大部分的IBinder 介面,除了onTransact() 和 queryLocalInterface(), getInterfaceDescriptor();
- BnInterface 實現了IBinder的queryLocalInterface()和getInterfaceDescriptor(), 但是其必須藉助實際的介面類。
- BnMediaPlayer只是定義了onTransact(), 沒有實現。
- onTransact()的具體實現在Client類。
為什麼搞得那麼複雜?Google 是希望通過這些封裝儘可能減少開發者的工作量,開發一個native的service 開發者只需要做這麼幾件事(上圖中深色部分):
- 定義一個介面檔案, IXXXService, 繼承IInterface
- 定義BnXXX(), 繼承 BnInterface<IXXXService>
- 實現一個XXXService類,繼承BnXXX(), 並具體實現onTransact() 函式。
Client端的實現:
- 使用和Server端同一個 IXXXService, 繼承IInterface
- 定義BpXXX(), 繼承 BpInterface<IXXXService)
- 實現一個XXXService類,繼承BpXXX(), 並具體實現transact() 函式。
Java層Binder的實現是採用了AIDL的方式。
Native | Java | Note(Java側說明) |
---|---|---|
IBinder | IBinder | |
IInterface | IInterface | |
IXXX | IXXX | AIDL檔案介面定義 |
BBinder | Binder | 通過JavaVBBinder類作為橋樑 |
BpBinder | BinderProxy | 通過JNI訪問Native的實現 |
BnInterface | N/A | |
BpInterface | N/A | |
BnXXX | Stub | AIDL自動生成,需使用者繼承在子類中實現真正的服務端操作 |
BpXXX | Proxy | AIDL自動生成,用於Client端呼叫 |
相關文章
- 理解 Android Binder 機制(二):C++層AndroidC++
- Android C++層使用Binder通訊的方法AndroidC++
- c++ binderC++
- Binder Java層的實現原理分析Java
- C++實現管理系統的示例程式碼C++
- Binder Java層分析Java
- [C++]實現memcpyC++memcpy
- Android Binder之旅Android
- 【 karle 專欄 】Android 初探底層知識系列——Binder原理。Android
- Android 音視訊 - EGL 原始碼解析以及 C++ 實現Android原始碼C++
- C++ 頂層const底層constC++
- 堆排序(實現c++)排序C++
- 命令模式(c++實現)模式C++
- LinkBlockedQueue的c++實現BloCC++
- 堆排序c++實現排序C++
- c++實現Json庫C++JSON
- Android系統服務編寫例項-Binder(Java層AIDL)AndroidJavaAI
- Android-Binder(一)Android
- Android實現雙層ViewPager巢狀AndroidViewpager巢狀
- [C++ & AdaBoost] 傻陳帶你用C++實現AdaBoostC++
- C++庫封裝JNI介面——實現java呼叫c++C++封裝Java
- C++筆記——C++基本思想與實現(一)C++筆記
- 字典樹及其C++實現C++
- 單例模式c++實現單例模式C++
- 享元模式(c++實現)模式C++
- 狀態模式(c++實現)模式C++
- 中介者模式(c++實現)模式C++
- 模板方法模式(c++實現)模式C++
- C++程式設計實現C++程式設計
- 橋接模式(c++實現)橋接模式C++
- FastASR——PaddleSpeech的C++實現ASTC++
- 折半查詢(C++實現)C++
- android NDK c++ libraryAndroidC++
- Android HAL 層框架分析以及程式碼示例Android框架
- mfc 讀寫 excel 示例 C++ libxlExcelC++
- android層java如何呼叫cocos2dx c++程式碼 步驟AndroidJavaC++
- C++過載底層原理C++
- HTTPS通訊的C++實現HTTPC++