binder通信简单实现过程

服务端实现

  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-exceptions
ifeq ($(TARGET_BUILD_PDK), true)
  rs_base_CFLAGS += -D__RS_PDK__
endif

ifneq ($(OVERRIDE_RS_DRIVER),)
  rs_base_CFLAGS += -DOVERRIDE_RS_DRIVER=$(OVERRIDE_RS_DRIVER)
endif

ifneq ($(DISABLE_RS_64_BIT_DRIVER),)
  rs_base_CFLAGS += -DDISABLE_RS_64_BIT_DRIVER
endif

ifeq ($(RS_FIND_OFFSETS), true)
  rs_base_CFLAGS += -DRS_FIND_OFFSETS
endif

include $(CLEAR_VARS)
ifneq ($(HOST_OS),windows)
LOCAL_CLANG := true
endif
LOCAL_MODULE := SoundPlaybackListen
LOCAL_MODULE_TARGET_ARCH_WARN := arm mips mips64 x86 x86_64 arm64

LOCAL_SRC_FILES:= \
SoundPlaybackListen.cpp \

LOCAL_SHARED_LIBRARIES += libRS libRSCpuRef libc++
LOCAL_SHARED_LIBRARIES += liblog libcutils libutils libEGL libGLESv1_CM libGLESv2
LOCAL_SHARED_LIBRARIES += libui libgui libsync

LOCAL_SHARED_LIBRARIES += libbcc libbcinfo libLLVM
LOCAL_SHARED_LIBRARIES += \
    libcutils \
    libbinder \
    libutils \
    libhardware

LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
LOCAL_C_INCLUDES += frameworks/rs/cpu_ref/linkloader/include
LOCAL_C_INCLUDES += external/libcxx/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/

LOCAL_CFLAGS += $(rs_base_CFLAGS)
LOCAL_CPPFLAGS += -fexceptions

LOCAL_MODULE_TAGS := optional

include $(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 yjd
int  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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
千里马8年Android系统及应用开发经验,曾担任过美国unokiwi公司移动端技术总监兼架构师,对系统开发,性能优化,应用高级开发有深入的研究,Android开源定制ROM Lineage的贡献者之一,国内首家线下开辟培训Android Framework课程,拥有2年的Android系统培训经验。成为腾讯课堂专业负责android framework课程分享第一人,致力于提高国内android Framework水平Android Framework领域内是国内各大手机终端科技公司需要的人才,应用开发者都对Android系统充满着好奇,其中的binder是重中之重,都说无binderAndroidbinde是Android系统的任督二脉。课程水平循序渐进,由中级再到高级,满足各个层次水平的android开发者。1、灵活使用binder跨进程通信,在app端对它的任何api方法等使用自如2、可以单独分析android系统源码中任何binder部分,分析再也没有难度3、掌握binder驱动本质原理,及对应binder驱动怎么进行跨进程通信,及内存等拷贝方式数据等4、对binder从上层的java app端一直到最底层的内核binder驱动,都可以顺利理通5、针对系统开发过程中遇到的binder报错等分析方法,及binder bug案例学习6、针对面试官任何的binder问题都可以对答自如7、socket这种跨进程通信实战使用8、针对android源码中使用的socket源码轻松掌握9、android系统源码中最常见的socketpair中双向跨进程通信10、使用socket实现一个可以让app执行shell命令的程序
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值