我是靠谱客的博主 清爽便当,最近开发中收集的这篇文章主要介绍Android中用C++实现Binder进程间通信(IPC C/S exe file powered by Android binder module in C++),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Android Binder frameworks 架構圖:



 /*************************
  *  IAmoService.cpp
  *  
  *
  *  editor: amo
  *************************/
#include <stdlib.h>
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <android/log.h>
#include <binder/TextOutput.h>

#include <IAmoService.h>

#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
using namespace android;

/* -------------------------------------------------------------------- */
/* my define macro                                                      */
/* -------------------------------------------------------------------- */
#if 0
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 
	const android::String16 I##INTERFACE::descriptor(NAME);
	const android::getInterfaceDescriptor() const {return I##INTERFACE::descriptor;}
	android::sp<I##INTERFACE> I##INTERFACE::asInterface(const android::sp<android::IBinder>& obj)
	{
		android::sp<I##INTERFACE> intr;
		if(obj != NULL){
			/* calls to sp<T>& sp<T>::operator=(T*), retrieves IAmoService object corresponding to IBinder bbinder pointed by sp<T> */ 
			intr = static_cast<I##INTERFACE*>(obj->queryLocalInterface(I##INTERFACE::descriptor).get());
			if(intr == NULL){
				/* calls to BpAmoService(const sp<IBinder>& impl) */
				intr = new Bp##INTERFACE(obj);
			}
		}
		return intr;	
	}
	I##INTERFACE::I##INTERFACE() {}
	I##INTERFACE::I##~INTERFACE() {}
#endif
//IMPLEMENT_META_INTERFACE(AmoService, "android.amo.service");

const android::String16 IAmoService::descriptor("android.amo.service");
const android::String16& IAmoService::getInterfaceDescriptor() const {return IAmoService::descriptor;} 
android::sp<IAmoService> IAmoService::asInterface(const sp<IBinder>& obj)
{
	android::sp<IAmoService> isvc;
	if(obj != NULL){
		isvc = static_cast<IAmoService*>(obj->queryLocalInterface(IAmoService::descriptor).get());
		if(isvc == NULL) isvc = new BpAmoService(obj);
	}
	return isvc;
}
IAmoService::IAmoService(){ALOGD("[IAmoService::IAmoService()]: ***:%p", this);}
IAmoService::~IAmoService(){ALOGD("[IAmoService::~IAmoService()]: ***:%p", this);}

/* -------------------------------------------------------------------- */
/* global variables                                                     */
/* -------------------------------------------------------------------- */

/* -------------------------------------------------------------------- */
/* implements                                                           */
/* -------------------------------------------------------------------- */
/*
BpAmoService::BpAmoService(const sp<IBinder>& impl) :
	BpInterface<IAmoService>(impl);
{
	ALOGD("[BpAmoService::BpAmService(sp<IBinder>&)]: ###n");
}
*/

void BpAmoService::amoLog()
{
	ALOGD("[BpAmoService::amoLog()]: >>>n");
	Parcel data, reply;
	data.writeInterfaceToken(IAmoService::descriptor);
	remote()->transact(AMO, data, &reply);
	ALOGD("[BpAmoService::amoLog()]: ... got reply:%dn", reply.readInt32());	
}

status_t BnAmoService::onTransact(uint_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
	ALOGD("[BnAmoService::onTransact()]: >>>(%x,%x)n", code, flags);
	switch(code){
		case AMO:
			ALOGD("[BnAmoService::onTransact()]: ... code is AMOn");
			CHECK_INTERFACE(IAmoService, data, reply);
			ALOGD("[BnAmoService::onTransact()]: ... going to amoLog()n");
			amoLog();
			ALOGD("[BnAmoService::onTransact()]: ... going to reply->writeInt32()n");
			reply->writeInt32(7589);
			break;
		default:
			ALOGD("[BnAmoService::onTransact()]: ... code is unknownn");
			BBinder::onTransact(code, data, reply, flags);
			break;
	}
	ALOGD("[BnAmoService::onTransact()]: ... finished:%dn", NO_ERROR);
	return NO_ERROR;
}

void BnAmoService::amoLog()
{
	ALOGD("[BnAmoService::amoLog()]: ### amo service heren");
}

通用header file:

#ifndef _I_AMO_SERVICE_H_
#define _I_AMO_SERVICE_H_

#include <stdio.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>

using namespace android;

class IAmoService : public IInterface
{
#if 0
#define DECLARE_META_INTERFACE(INTERFACE) 
	static const android::String16 descriptor;
	static android::sp<I##INTERFACE> asInterface(const android::sp<android::IBinder>& obj);
	virtual const android::String16& getInterfaceDescriptor() const;
	I##INTERFACE();
	virtual ~I##INTERFACE();
#endif
public:
	enum{
		AMO = 1
	};
	DECLARE_META_INTERFACE(AmoService);
	virtual void amoLog() = 0; 
};

class BpAmoService : public BpInterface<IAmoService>
{
	public:
		BpAmoService(const sp<IBinder>& impl): BpInterface<IAmoService>(impl){
			ALOGD("[BpAmoService::BpAmService(sp<IBinder>&)]: ###n");
		}
		virtual void amoLog();
};

class BnAmoService : public BnInterface<IAmoService>
{
	public:
		virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flag=0);
		virtual void amoLog();
};


#endif

Client source:

 /*************************
  *  main_client.cpp
  *  
  *
  *  editor: amo
  *************************/
#include <stdlib.h>
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <android/log.h>

#include <IAmoService.h>

#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
using namespace android;

/* -------------------------------------------------------------------- */
/* my define macro                                                     */
/* -------------------------------------------------------------------- */

/* -------------------------------------------------------------------- */
/* global variables                                                     */
/* -------------------------------------------------------------------- */
sp<IServiceManager> sm;
sp<IBinder> bpbinder;
sp<IAmoService> isvc;

/* -------------------------------------------------------------------- */
/* implements                                                           */
/* -------------------------------------------------------------------- */
int main(__unused int argc, __unused char **argv)
{
	ALOGD("[main_client]: >>>");
	sm = defaultServiceManager();
	if(!sm){
		ALOGD("[main_client]: !!! sm is null");
		goto exit;
	}
	bpbinder = sm->getService(IAmoService::descriptor);
	if(!bpbinder){
		ALOGD("[main_client]: !!! bpbinder is null");
		goto exit;
	}
	isvc = interface_cast<IAmoService>(bpbinder);
	if(!isvc){
		ALOGD("[main_client]: !!! isvc is null");
		goto exit;
	}
	ALOGD("[main_client]: ... going to isvc->amoLog()");
	isvc->amoLog();
	
exit:	
	ALOGD("[main_client]: ... finished");
	return 0;
}

Server source: 

 /*************************
  *  main_server.cpp
  *  
  *
  *  editor: amo
  *************************/
#include <stdlib.h>
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <android/log.h>

#include <IAmoService.h>

#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
using namespace android;

/* -------------------------------------------------------------------- */
/* my define macro                                                     */
/* -------------------------------------------------------------------- */

/* -------------------------------------------------------------------- */
/* global variables                                                     */
/* -------------------------------------------------------------------- */
sp<IServiceManager> sm;

/* -------------------------------------------------------------------- */
/* implements                                                           */
/* -------------------------------------------------------------------- */
int main(__unused int argc, __unused char **argv)
{
	ALOGD("[main_server]: >>>");
	sm = defaultServiceManager();
	if(!sm){
		ALOGD("[main_server]: !!! sm is null");
		goto exit;
	}
	sm->addService(IAmoService::descriptor, new BnAmoService());
	ALOGD("[main_server]: going to ProcessState::self()->startThreadPool()");
	ProcessState::self()->startThreadPool();
	ALOGD("[main_server]: after ProcessState::self()->startThreadPool()");

	ALOGD("[main_server]: going to IPCThreadState::self()->joinThreadPool()");
	IPCThreadState::self()->joinThreadPool();
	ALOGD("[main_server]: after IPCThreadState::self()->joinThreadPool()");
exit:	
	ALOGD("[main_server]: ... finished");
	return 0;
}

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := amos
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := ./

LOCAL_SRC_FILES += 	main_server.cpp 
					IAmoService.cpp
LOCAL_SHARED_LIBRARIES := libutils libcutils libbinder liblog
LOCAL_C_INCLUDES += frameworks/native/include system/core/include
include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)
LOCAL_MODULE := amoc
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := ./
					
LOCAL_SRC_FILES += 	main_client.cpp 
					IAmoService.cpp
LOCAL_SHARED_LIBRARIES := libutils libcutils libbinder liblog
LOCAL_C_INCLUDES += frameworks/native/include system/core/include
include $(BUILD_EXECUTABLE)
建議在Android BSP內編譯
去https://source.android.com/source/downloading.html
- `cd <RepoTop>`
- `source build/envsetup.sh`
- `lunch`
- `cd <RepoTop>/external`
- `cd 一個裝了這些程式碼的資料夾名稱`
- `mm`
- The binary "amoc" and "amos" should be in `<RepoTop>/out/target/product/*/system/bin/binder`.
  Copy it to /system/bin/ on the phone.


在Android手機內執行,並使用adb logcat 觀察IPC的訊息。

最后

以上就是清爽便当为你收集整理的Android中用C++实现Binder进程间通信(IPC C/S exe file powered by Android binder module in C++)的全部内容,希望文章能够帮你解决Android中用C++实现Binder进程间通信(IPC C/S exe file powered by Android binder module in C++)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部