apk(java binder client) 与 Native Service 通信
- Android 4.4
- 无需JNI Client
- Native service (具有root权限)
- 通过Parcel在java与c++传输数据
- IBinder.onTransact 通信原理
- 仅适用于系统开发人员(能够拿到源码编译后的android库)
native service 的编写
首先展示下目录结构
NativeService.h
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#define TRANSACTION_execCmd FIRST_CALL_TRANSACTION + 1
using namespace android;
namespace nativeservice
{
class NativeService : public BBinder
{
private:
public:
static int Instance();
NativeService();
virtual ~NativeService();
virtual status_t onTransact(uint32_t,
const Parcel&, Parcel*, uint32_t);
};
}
NativeService.cpp
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "NativeService.h"
namespace nativeservice
{
int NativeService::Instance()
{
sp<IServiceManager> SM = defaultServiceManager();
String16 str16Key = String16("nativeservice");
sp<IBinder> nativeService = new NativeService();
//注册服务
return SM -> addService(str16Key, nativeService);
}
NativeService::NativeService()
{
LOGV("NativeService create\n");
}
NativeService::~NativeService()
{
LOGV("NativeService destory\n");
}
//重点在这,处理client(可以是c++/java)来的的请求
status_t NativeService::onTransact(uint32_t code,
const Parcel& data, Parcel* reply, uint32_t flags)
{
case TRANSACTION_execCmd:
{
LOGV("execCmd\n");
//读取client传过来的key,可用作安全判断,这里不做处理,但是一定要调用这段代码,把数据指针偏移到下个数据端,对于Parcel,客户端与服务端都要一一对应,否则数据传递会出错!!!!
data.enforceInterface(String16(REMOTE_KEY));
//读取client传过来的参数(命令)
String16 cmd = data.readString16();
char cResult[1024] = {
0};
//这里是我自己的操作,根据自己的情况调用
m_SystemCommand.execCmd(cmd, cResult, 1024);
String16 str16Result = String16(cResult);
//写入异常code,"0"表示没有异常
reply -> writeInt32(0);
//写入返回到client的返回数据
reply -> writeString16(str16R