Android Binder機制的Native應用—雙向通訊
阿新 • • 發佈:2019-01-27
mkdir testbinder //建立testbinder目錄
Android.mk
include $(call all-subdir-makefiles)
一、介面類
1.正向呼叫—Itestbinder
Itestbinder.h
Itestbinder.cpp#ifndef Itestbinder_H #define Itestbinder_H #include <binder/IInterface.h> #include "Icallback.h" namespace android{ class Itestbinder : public IInterface{ public: DECLARE_META_INTERFACE(testbinder); virtual int testinterface(int a) = 0; virtual int setcallback(const sp<Icallback>& callback) = 0; }; class Bntestbinder : public BnInterface<Itestbinder>{ public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; } #endif
2.反向呼叫—Icallback#include "Itestbinder.h" #include <binder/Parcel.h> #include <binder/IInterface.h> #include "Icallback.h" namespace android{ enum { TEST_INTERFACE, SET_CALLBACK }; //////////////////客戶端 class Bptestbinder : public BpInterface<Itestbinder>{ public: Bptestbinder(const sp<IBinder>& impl) : BpInterface<Itestbinder>(impl){ } virtual int testinterface(int a){ LOGD("==========================================================\n"); LOGD("TK---->>>>>>Itestbinder.cpp>>>>Bptestbinder::testinterface\n"); Parcel data,reply; data.writeInt32(a); remote()->transact(TEST_INTERFACE,data,&reply); return reply.readInt32(); } virtual int setcallback(const sp<Icallback>& callback){ LOGD("==========================================================\n"); LOGD("TK---->>>>>>Itestbinder.cpp>>>>Bptestbinder::setcallback\n"); Parcel data, reply; data.writeStrongBinder(callback->asBinder()); remote()->transact(SET_CALLBACK, data, &reply); return reply.readInt32(); } }; IMPLEMENT_META_INTERFACE(testbinder, "android.test.Itestbinder"); /////////////////服務端 status_t Bntestbinder::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ LOGD("TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact\n"); switch (code) { case TEST_INTERFACE:{ //CHECK_INTERFACE(Itestbinder, data, reply); LOGD("TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact>>TEST_INTERFACE\n"); reply->writeInt32(testinterface((int) data.readInt32()) ); return NO_ERROR; } break; case SET_CALLBACK:{ LOGD("TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact>>SET_CALLBACK\n"); sp<Icallback> callback = interface_cast<Icallback>(data.readStrongBinder()); //int a = connect(Client); reply->writeInt32(setcallback(callback)); return NO_ERROR; } default:{ LOGD("TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact>>333\n"); return BBinder::onTransact(code, data, reply, flags); } } } }
Icallback.h
Icallback.cpp#ifndef Icallback_H #define Icallback_H #include <binder/IInterface.h> namespace android{ class Icallback : public IInterface{ public: DECLARE_META_INTERFACE(callback); virtual int notifyCallback(int a) = 0; }; class Bncallback : public BnInterface<Icallback>{ public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; } #endif
#include "Itestbinder.h"
#include <binder/Parcel.h>
#include <binder/IInterface.h>
namespace android{
enum {
NOTIFY_CALLBACK,
};
//////////////////客戶端
class Bpcallback : public BpInterface<Icallback>{
public:
Bpcallback(const sp<IBinder>& impl) : BpInterface<Icallback>(impl){
}
virtual int notifyCallback(int a){
LOGD("==========================================================\n");
LOGD("TK---->>>>>>Icallback.cpp>>>>Bpcallback::notifyCallback\n");
Parcel data,reply;
data.writeInt32(a);
remote()->transact(NOTIFY_CALLBACK,data,&reply);
return reply.readInt32();
}
};
IMPLEMENT_META_INTERFACE(callback, "android.test.Icallback");
/////////////////服務端
status_t Bncallback::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
LOGD("TK---->>>>>>Icallback.cpp>>>>Bncallback::onTransact\n");
switch (code) {
case NOTIFY_CALLBACK:{
//CHECK_INTERFACE(Itestbinder, data, reply);
LOGD("TK---->>>>>>Icallback.cpp>>>>Bncallback::onTransact>>NOTIFY_CALLBACK\n");
reply->writeInt32(notifyCallback((int) data.readInt32()) );
return NO_ERROR;
} break;
default:{
LOGD("TK---->>>>>>Icallback.cpp>>>>Bncallback::onTransact>>222\n");
return BBinder::onTransact(code, data, reply, flags);
}
}
}
}
二、服務端mkdir server //建立server目錄,這個是服務端實現
1.Bntestbinder實現
testbinder.h
#include "../interface/Itestbinder.h"
#include "../interface/Icallback.h"
#include <binder/BinderService.h>
namespace android{
class testbinder:
public BinderService<testbinder>,
public Bntestbinder{
friend class BinderService<testbinder>;
public:
static const char* getServiceName() { return "test.Itestbinder"; }
virtual int testinterface(int a);
virtual int setcallback(const sp<Icallback>& callback);
virtual status_t onTransact(
uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags);
protected:
sp<Icallback> mcallback;
};
}
testbinder.cpp#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
//#include <utils/Trace.h>
#include <binder/Parcel.h>
#include <binder/IPCThreadState.h>
#include <utils/String16.h>
#include <utils/threads.h>
#include <utils/Atomic.h>
//#include <cutils/bitops.h>
#include <cutils/properties.h>
#include <cutils/compiler.h>
#include "testbinder.h"
namespace android{
int testbinder::testinterface(int a){
LOGD("TK---->>>>>>testbinder.cpp>>>>testbinder::testinterface\n");
sp<Icallback> c = mcallback;
c->notifyCallback(2);
return a+2;
}
int testbinder::setcallback(const sp<Icallback>& callback){
LOGD("TK---->>>>>>testbinder.cpp>>>>testbinder::setcallback\n");
mcallback = callback;
return 1;
}
status_t testbinder::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
LOGD("TK---->>>>>>testbinder.cpp>>>>testbinder::onTransact\n");
return Bntestbinder::onTransact(code, data, reply, flags);
}
}
2.向ServiceManager註冊testbinder服務
main.cpp#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include "testbinder.h"
using namespace android;
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
testbinder::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
Android.mkLOCAL_PATH:= $(call my-dir)
#LOCAL_CFLAGS_ALL :=-I. -I$(LOCAL_PATH)/..
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
main.cpp \
testbinder.cpp \
../interface/Itestbinder.cpp \
../interface/Icallback.cpp
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
libdl
LOCAL_MODULE:= server
LOCAL_MODULE_TAGS := optional
三、客戶端
1.通過ServiceManager獲得Itestbinder遠端介面
mkdir client //建立client目錄,這個是client的實現
client.h
#include "../interface/Itestbinder.h"
namespace android{
class client{
public:
static const sp<Itestbinder>& get_test_binder();
static sp<Itestbinder> gtestbinder;
};
}
client.cpp#include "client.h"
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <stdio.h>
namespace android{
sp<Itestbinder> client::gtestbinder;
const sp<Itestbinder>& client::get_test_binder(){
if (gtestbinder == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("test.Itestbinder"));
if (binder != 0)
break;
printf("testbinder not published, waiting...");
usleep(500000); // 0.5 s
} while (true);
gtestbinder = interface_cast<Itestbinder>(binder);
}
if(gtestbinder==0) printf("no testbinder!?");
return gtestbinder;
}
}
2.Bncallback的實現,反向呼叫callback.h
#include "../interface/Itestbinder.h"
#include "../interface/Icallback.h"
#include <binder/BinderService.h>
namespace android{
class callback: public Bncallback{
friend class BinderService<callback>;
public:
virtual int notifyCallback(int a);
virtual status_t onTransact(
uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags);
};
}
callback.cpp#include <binder/Parcel.h>
#include <binder/IPCThreadState.h>
#include <utils/String16.h>
#include <utils/threads.h>
#include <utils/Atomic.h>
//#include <cutils/bitops.h>
#include <cutils/properties.h>
#include <cutils/compiler.h>
#include "callback.h"
namespace android{
int callback::notifyCallback(int a){
LOGD("TK---->>>>>>callback.cpp>>>>callback::notifyCallback\n");
return 1;
}
status_t callback::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
LOGD("TK---->>>>>>callback.cpp>>>>callback::onTransact\n");
return Bncallback::onTransact(code, data, reply, flags);
}
}
3.主函式main.cpp
#include <stdio.h>
#include "client.h"
#include "callback.h"
using namespace android;
int main(int argc, char* argv[]){
client* myclient = new client();
if(myclient == NULL) return 0;
const sp<Itestbinder>& tb = myclient->get_test_binder();
if(tb == NULL) return 0;
sp<callback> c = new callback();
ProcessState::self()->startThreadPool(); //add by tank
int a = tb->setcallback(c);
a = tb->testinterface(3);
LOGD("TK-------->>>result is %d\n",a);
delete myclient;
return 0;
}
Android.mkLOCAL_PATH:= $(call my-dir)
#LOCAL_CFLAGS_ALL :=-I. -I$(LOCAL_PATH)/..
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
client.cpp \
main.cpp \
../interface/Itestbinder.cpp \
callback.cpp \
../interface/Icallback.cpp \
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
libdl
LOCAL_MODULE:= client
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
四、執行./server
./client
結果:
result:
I/ ( 563): ServiceManager: 0xd750
D/ ( 565): ==========================================================
D/ ( 565): TK---->>>>>>Itestbinder.cpp>>>>Bptestbinder::setcallback
D/ ( 563): TK---->>>>>>testbinder.cpp>>>>testbinder::onTransact
D/ ( 563): TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact
D/ ( 563): TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact>>SET_CALLBACK
D/ ( 563): TK---->>>>>>testbinder.cpp>>>>testbinder::setcallback
D/ ( 565): ==========================================================
D/ ( 565): TK---->>>>>>Itestbinder.cpp>>>>Bptestbinder::testinterface
D/ ( 563): TK---->>>>>>testbinder.cpp>>>>testbinder::onTransact
D/ ( 563): TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact
D/ ( 563): TK---->>>>>>Itestbinder.cpp>>>>Bntestbinder::onTransact>>TEST_INTERFACE
D/ ( 563): TK---->>>>>>testbinder.cpp>>>>testbinder::testinterface
D/ ( 563): ==========================================================
D/ ( 563): TK---->>>>>>Icallback.cpp>>>>Bpcallback::notifyCallback
D/ ( 565): TK---->>>>>>callback.cpp>>>>callback::onTransact
D/ ( 565): TK---->>>>>>Icallback.cpp>>>>Bncallback::onTransact
D/ ( 565): TK---->>>>>>Icallback.cpp>>>>Bncallback::onTransact>>NOTIFY_CALLBACK
D/ ( 565): TK---->>>>>>callback.cpp>>>>callback::notifyCallback
D/ ( 565): TK-------->>>result is 5