binder通信简单实现过程

来源:互联网 发布:巅峰网络传奇 编辑:程序博客网 时间:2024/06/06 18:52

服务端实现

  1. SoundPlaybackListen.h
#ifndef SOUND_PLAYBACK_LISTEN_H#define SOUND_PLAYBACK_LISTEN_H#include <binder/IServiceManager.h>#include <binder/IBinder.h>#include <binder/Parcel.h>#include <binder/ProcessState.h>#include <binder/IPCThreadState.h>#include <private/binder/binder_module.h>#include <android/log.h>#include <netinet/in.h>    // for sockaddr_in#include <sys/types.h>    // for socket#include <sys/socket.h>    // for socket#include <stdio.h>        // for printf#include <stdlib.h>        // for exit#include <string.h>        // for bzero#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/time.h>   #include <unistd.h> #include <stdio.h>#include <unistd.h>#include <signal.h>#include <sstream>#include "SocketException.h"#include <iostream>using namespace android;#ifdef LOG_TAG#undef LOG_TAG#endif#define LOG_TAG "SoundPlaybackListen"#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "SoundPlaybackListen", __VA_ARGS__)#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "SoundPlaybackListen", __VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO  , "SoundPlaybackListen", __VA_ARGS__)#define LOGW(...) __android_log_print(ANDROID_LOG_WARN  , "SoundPlaybackListen", __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , "SoundPlaybackListen", __VA_ARGS__)enum{    PLAYBACKSTART = 1,    PLAYBACKSTOP = 2,};class SoundPlaybackListen: public BBinder{public:    SoundPlaybackListen();    ~SoundPlaybackListen();public:    int playbackStart();    int playbackPause();    int playbackStop();    void closeFd(int sockfd);    static void* sendTcpData(void* arg);    //上报数据到应用层    static int init_thread(int data);    virtual status_t onTransact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags );private:    String16 SoundPlaybackDescriptor;    sp<IBinder> mIBinder;    int mState;public:};#endif
  1. SoundPlaybackListen.cpp(这里主要涉及到一个C++中使用pthread_create()函数)

在进行简单的参数传递的时候,比如传递一个int型的数据,只需要使用int(arg)进行转换即可,万万不能进行地址之类的转换。还有一个知识点就是如果线程中要用到类中的成员,可以在类中定义一个Object pThis,然后在构造函数中对这个pThis = this进行赋值,pthread_create参数传递的时候直接将这个pThis 传递给线程函数,线程函数中再将pThis 从void 转换到Object *即可使用pThis 中的成员了。

#include <media/SoundPlaybackListen.h>SoundPlaybackListen::SoundPlaybackListen(){    mState = 0;    LOGD("SoundPlaybackListen Create...");    SoundPlaybackDescriptor = String16("sound.playback.listen");}status_t SoundPlaybackListen::onTransact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags){        int ret = -1;          LOGD("-----enter SoundPlaybackListen onTransact and the code is %d", code);         switch (code)         {             case 1:                ret = playbackStart();                //reply->writeInt32(ret);                 break;             case 2:                ret = playbackStop();                //reply->writeInt32(ret);                 break;             case 3:                 ret = playbackPause();                 //reply->writeInt32(ret);                  break;             default:                 return BBinder::onTransact(code, data, reply, flags);         }         return 0;}int SoundPlaybackListen::init_thread(int data){    pthread_t mPid;    LOGD("data = %d\n", data);    int sendData = data;    int ret = pthread_create(&mPid, 0, sendTcpData, (void *)sendData);    if(ret != 0)    {        LOGD("uart_queue_write_id thread create error:\n");        return -1;    }    return 0;}void* SoundPlaybackListen::sendTcpData(void *arg){    char  revBuf[16], sendData[8];    LOGD("arg = %d\n", int(arg));    sprintf(sendData, "%d", int(arg));    int client_socket = socket(AF_INET,SOCK_STREAM,0);    if( client_socket < 0)    {        LOGD("Create Socket Failed!\n");        return NULL;    }    LOGD("start to connect server....");    //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口    struct sockaddr_in server_addr;    bzero(&server_addr,sizeof(server_addr));    server_addr.sin_family = AF_INET;    if(inet_aton("127.0.0.1", &server_addr.sin_addr) == 0) //服务器的IP地址来自程序的参数    {        LOGD("Server IP Address Error!\n");        if(client_socket > 0)            close(client_socket);    }    server_addr.sin_port = htons(8898);    socklen_t server_addr_length = sizeof(server_addr);    LOGD("sendData is: %s ", sendData);    //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接    //int flags = fcntl(client_socket, F_GETFL, 0);//获取建立的sockfd的当前状态(非阻塞)    //fcntl(client_socket , F_SETFL,flags|O_NONBLOCK);//将当前sockfd设置为非阻塞    if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)    {        if(client_socket > 0)            close(client_socket);        return NULL;    }    LOGD("strlen(sendData) = %d", strlen(sendData));    //向服务器发送buffer中的数据    int len = send(client_socket, sendData, strlen(sendData) , 0);    LOGD("send len =  %d", len);    char buffer[128];    while( len = recv(client_socket, buffer, 128, 0))    {        if(len < 0)        {            LOGD("Recieve Data From Server Failed!\n");            break;        }        LOGD("recv buffer is :%s",buffer);        bzero(buffer, 128);        }    if(client_socket > 0)        close(client_socket);        LOGD("pthread_exit.....");    pthread_exit(NULL);}int SoundPlaybackListen::playbackStart(){    LOGD("playbackStart Start");    mState++;    int sendState = -1;    LOGD("mState = %d\n", mState);    if( mState <= 0)    {        sendState = 0;    }    else    {        sendState = 1;    }    init_thread(sendState);    LOGD("playbackStart end");    return 0;}int SoundPlaybackListen::playbackPause(){    LOGD("playbackStart Pause");     mState--;    LOGD("mState = %d\n", mState);    int sendState = -1;    if( mState <= 0)    {        sendState = 0;    }    else    {        sendState = 1;    }    init_thread(sendState);    LOGD("playbackStart Stop end");     return 1;}int SoundPlaybackListen::playbackStop(){    LOGD("playbackStart Stop");     if( mState > 0)        mState--;    LOGD("mState = %d\n", mState);    int sendState = -1;    if( mState <= 0)    {        sendState = 0;    }    else    {        sendState = 1;    }    init_thread(sendState);    LOGD("playbackStart Stop end");     return 1;}SoundPlaybackListen::~SoundPlaybackListen(){    LOGD("SoundPlaybackListen Delete...");}int main(){    sp<IServiceManager> sm = defaultServiceManager(); //获取ServiceManager服务代理    status_t ret;    //register SoundPlaybackListen to ServiceManager    SoundPlaybackListen* mSoundPlaybackListen = new SoundPlaybackListen();    ret = sm->addService(String16("sound.playback.listen"), mSoundPlaybackListen); // 注册服务    LOGD("sound.playback.listen return %d", ret);    //call binder thread pool to start    ProcessState::self()->startThreadPool();    IPCThreadState::self()->joinThreadPool(true); //参数默认也是true,进入服务的循环监听状态    return 0;}
  1. Android.mk(要编译C++代码,Android.mk要包含以下内容)
LOCAL_PATH:=$(call my-dir)rs_base_CFLAGS :=  -Wall -Wno-unused-parameter -Wno-unused-variable -fno-exceptionsifeq ($(TARGET_BUILD_PDK), true)  rs_base_CFLAGS += -D__RS_PDK__endififneq ($(OVERRIDE_RS_DRIVER),)  rs_base_CFLAGS += -DOVERRIDE_RS_DRIVER=$(OVERRIDE_RS_DRIVER)endififneq ($(DISABLE_RS_64_BIT_DRIVER),)  rs_base_CFLAGS += -DDISABLE_RS_64_BIT_DRIVERendififeq ($(RS_FIND_OFFSETS), true)  rs_base_CFLAGS += -DRS_FIND_OFFSETSendifinclude $(CLEAR_VARS)ifneq ($(HOST_OS),windows)LOCAL_CLANG := trueendifLOCAL_MODULE := SoundPlaybackListenLOCAL_MODULE_TARGET_ARCH_WARN := arm mips mips64 x86 x86_64 arm64LOCAL_SRC_FILES:= \SoundPlaybackListen.cpp \LOCAL_SHARED_LIBRARIES += libRS libRSCpuRef libc++LOCAL_SHARED_LIBRARIES += liblog libcutils libutils libEGL libGLESv1_CM libGLESv2LOCAL_SHARED_LIBRARIES += libui libgui libsyncLOCAL_SHARED_LIBRARIES += libbcc libbcinfo libLLVMLOCAL_SHARED_LIBRARIES += \    libcutils \    libbinder \    libutils \    libhardwareLOCAL_C_INCLUDES += frameworks/compile/libbcc/includeLOCAL_C_INCLUDES += frameworks/rs/cpu_ref/linkloader/includeLOCAL_C_INCLUDES += external/libcxx/includeLOCAL_C_INCLUDES += $(LOCAL_PATH)/include/LOCAL_CFLAGS += $(rs_base_CFLAGS)LOCAL_CPPFLAGS += -fexceptionsLOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)

客户端实现

AudioTrack.cpp

#include <binder/IServiceManager.h>#include <binder/IBinder.h>#include <binder/Parcel.h>#include <binder/ProcessState.h>#include <binder/IPCThreadState.h>#include <private/binder/binder_module.h>#include <android/log.h>//and by yjdint  AudioTrack::playbackStart(){    sp<IServiceManager> sm = defaultServiceManager();   //获取ServiceManager服务代理    sp<IBinder> mIBinder = sm->getService(String16("sound.playback.listen")); //查询服务    if (mIBinder == NULL)    {        ALOGI("Can't find binder service \"sound.playback.listen\"");        return -1;    }    Parcel in, out;     AudioTrack *mAudioTrack = new AudioTrack();    //in.writeStrongBinder(sp<IBinder>(mAudioTrack));    int ret = mIBinder->transact(1, in, &out, 0);      ////这里的1对应服务端onTransact中code的1    ALOGI("playbackStart return %d", ret);    return 0;}int  AudioTrack::playbackStop(){    sp<IServiceManager> sm = defaultServiceManager();   //获取ServiceManager服务代理    sp<IBinder> mIBinder = sm->getService(String16("sound.playback.listen")); //查询服务    if (mIBinder == NULL)    {        ALOGI("Can't find binder service \"sound.playback.listen\"");        return -1;    }    Parcel in, out;     //AudioTrack *mAudioTrack = new AudioTrack();    //in.writeStrongBinder(sp<IBinder>(mAudioTrack));    int ret = mIBinder->transact(2, in, &out, 0);  //这里的2对应服务端onTransact中code的2    ALOGI("playbackStart return %d");    return 0;}