服务端
书写思路:
Server 端继承自 BBinder
class BBinder : public IBinder
继承的关键方法:
//注册到 ServiceManager 的名称
public:
virtual const String16 &getInterfaceDescriptor() const {
return myDescriptor;
};
//用于发送数据
protected:
// NOLINTNEXTLINE(google-default-arguments)
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0) final;
//用于接收数据
// NOLINTNEXTLINE(google-default-arguments)
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
onTransact 如何解析数据并发送给客户端: 首先判断 code,然后从 data 中 readStrongBinder 获取 iBinder 对象,创建一个新的 Parcel 对象并写入数据,最后通过 iBinder 的 transact 方法,回调给客户端数据。当然也可以从 data 中读取其他从客户端写入的信息。
将服务端注册到 ServiceManager
#include <binder/IServiceManager.h>
int main(){
sp<IServiceManager> sm = defaultServiceManager();
sp<MySampleService> mySampleService = new MySampleService();
sm->addService(String16(SAMPLE_SERVICE_DES),mySampleService);
ALOGD("Service addService");
printf("server before joinThreadPool \n");
IPCThreadState::self() ->joinThreadPool(true);
printf("server after joinThreadPool \n");
return 0;
}
服务端代码
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
using namespace android;
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "myCppBinder"
#define SAMPLE_SERVICE_DES "my_hello"
#define SAMPLE_CB_SERVICE_DES "android.os.MySampleCallBack"
#define SRV_CODE 1
#define CB_CODE 1
class MySampleService : public BBinder {
private:
String16 myDescriptor;
sp <IBinder> callback;
public:
MySampleService() {
ALOGE("My Server ---------------------------%d", __LINE__);
myDescriptor = String16(SAMPLE_SERVICE_DES);
}
virtual ~MySampleService() {
}
virtual const String16 &getInterfaceDescriptor() const {
return myDescriptor;
};
protected:
void callFunction(int val) {
ALOGE("Server ----------------------- %d", __LINE__);
ALOGI("Service: %s(), %d, val = %d", __FUNCTION__, __LINE__, val);
}
virtual status_t onTransact(uint32_t
code,
const Parcel &data, Parcel
*reply,
uint32_t flags = 0
) {
ALOGD("Service onTransact,line = %d, code = %d", __LINE__, code);
String8 str_1;
bool ret;
switch (code) {
case SRV_CODE:
//read Client pass IBinder Object
callback = data.readStrongBinder();
ret = data.checkInterface(callback.get());
ALOGD("Service onTransact,checkInterface line = %d, ret = %d", __LINE__, ret);
str_1 = data.readString8();
ALOGD("Service onTransact,readString8 line = %d, ret = %s", __LINE__, str_1.string());
if (callback != NULL) {
Parcel _data, _replay;
_data.writeInt32(1);
_data.writeInt32(2);
_data.writeInt32(3);
_data.writeString8(String8("who..."));
_data.writeString8(String8("are..."));
_data.writeString8(String8("you..."));
callback->transact(CB_CODE, _data, &_replay, 0);
}
callFunction(6666);
break;
default:
return BBinder::onTransact(CB_CODE, data, reply, flags);
}
return 0;
}
};
int main(){
sp<IServiceManager> sm = defaultServiceManager();
sp<MySampleService> mySampleService = new MySampleService();
sm->addService(String16(SAMPLE_SERVICE_DES),mySampleService);
ALOGD("Service addService");
printf("server before joinThreadPool \n");
IPCThreadState::self() ->joinThreadPool(true);
printf("server after joinThreadPool \n");
return 0;
}
客户端
书写思路:
MySampleCallBack 思路和 Server 基本一样。只是不需要从 data 中获取 iBinder 对象。直接从 ServiceManager 中获取。
class MySampleCallBack : public BBinder
int main() {
sp <IServiceManager> sm = defaultServiceManager();
sp <IBinder> iBinder = sm->getService(String16(SAMPLE_SERVICE_DES));
if (iBinder == NULL) {
ALOGW("client can't find service");
return -1;
}
Parcel _data, _replay;
sp <MySampleCallBack> mySampleCallBack = new MySampleCallBack();
_data.writeStrongBinder(mySampleCallBack);
_data.writeInterfaceToken(String16(SAMPLE_CB_SERVICE_DES));
_data.writeString8(String8("Hello My Server!!"));
iBinder->transact(SRV_CODE, _data, &_replay, 0);
printf("Client before joinThreadPool \n");
IPCThreadState::self()->joinThreadPool(true);
printf("Client ------------------------------ main end");
return 0;
}
客户端代码
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/Binder.h>
using namespace android;
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "binderCallbackClient"
#define SAMPLE_SERVICE_DES "my_hello" //和服务端一致
#define SAMPLE_CB_SERVICE_DES "android.os.MySampleCallBack" //和服务端一致
#define SRV_CODE 1
#define CB_CODE 1
class MySampleCallBack : public BBinder {
private:
String16 myDescriptor;
public:
MySampleCallBack() {
ALOGE("Client ------------------------------ %d", __LINE__);
myDescriptor = String16(SAMPLE_CB_SERVICE_DES);
}
virtual ~MySampleCallBack() {}
virtual const String16 &getInterfaceDescriptor() const {
return myDescriptor;
}
protected:
void callFunction(int val) {
ALOGD("---------callback client ok --------- line: %d, val :%d", __LINE__, val);
}
virtual status_t onTransact(uint32_t code,
const Parcel &data,
Parcel *reply,
uint32_t flags = 0) {
ALOGD("Client onTransact, line = %d, code = %d", __LINE__, code);
int val_1, val_2, val_3;
String8 str_1, str_2, str_3;
switch (code) {
case SRV_CODE: {
val_1 = data.readInt32();
val_2 = data.readInt32();
val_3 = data.readInt32();
ALOGE("Client ------------------------------ %d, read int32 = %d", __LINE__, val_1);
ALOGE("Client ------------------------------ %d, read int32 = %d", __LINE__, val_2);
ALOGE("Client ------------------------------ %d, read int32 = %d", __LINE__, val_3);
str_1 = data.readString8();
str_2 = data.readString8();
str_3 = data.readString8();
ALOGE("Client ------------------------------ %d, read String = %s", __LINE__,
str_1.string());
ALOGE("Client ------------------------------ %d, read String = %s", __LINE__,
str_2.string());
ALOGE("Client ------------------------------ %d, read String = %s", __LINE__,
str_3.string());
callFunction(12349);
break;
}
default: {
return BBinder::onTransact(code, data, reply, flags);
}
}
return 0;
}
};
int main() {
sp <IServiceManager> sm = defaultServiceManager();
sp <IBinder> iBinder = sm->getService(String16(SAMPLE_SERVICE_DES));
if (iBinder == NULL) {
ALOGW("client can't find service");
return -1;
}
Parcel _data, _replay;
sp <MySampleCallBack> mySampleCallBack = new MySampleCallBack();
_data.writeStrongBinder(mySampleCallBack);
_data.writeInterfaceToken(String16(SAMPLE_CB_SERVICE_DES));
_data.writeString8(String8("Hello My Server!!"));
iBinder->transact(SRV_CODE, _data, &_replay, 0);
printf("Client before joinThreadPool \n");
IPCThreadState::self()->joinThreadPool(true);
printf("Client ------------------------------ main end");
return 0;
}
打印结果
1979 1979 E myCppBinder: My Server ---------------------------25
1979 1979 D myCppBinder: Service addService
1981 1981 E binderCallbackClient: Client ------------------------------ 27
1979 1979 D myCppBinder: Service onTransact,line = 49, code = 1
1981 1981 D binderCallbackClient: Client onTransact, line = 46, code = 1598968902
1979 1979 D myCppBinder: Service onTransact,checkInterface line = 57, ret = 1
1979 1979 D myCppBinder: Service onTransact,readString8 line = 59, ret = Hello My Server!!
1981 1981 D binderCallbackClient: Client onTransact, line = 46, code = 1
1981 1981 E binderCallbackClient: Client ------------------------------ 56, read int32 = 1
1981 1981 E binderCallbackClient: Client ------------------------------ 57, read int32 = 2
1981 1981 E binderCallbackClient: Client ------------------------------ 58, read int32 = 3
1981 1981 E binderCallbackClient: Client ------------------------------ 64, read String = who...
1981 1981 E binderCallbackClient: Client ------------------------------ 66, read String = are...
1981 1981 E binderCallbackClient: Client ------------------------------ 68, read String = you...
1981 1981 D binderCallbackClient: ---------callback client ok --------- line: 39, val :12349
1979 1979 E myCppBinder: Server ----------------------- 39
1979 1979 I myCppBinder: Service: callFunction(), 40, val = 6666