千里马Android Framework实战开发-native程序之间binder通信实战案例分析

107 篇文章 12 订阅
72 篇文章 0 订阅

csdn在线学习课程,课程咨询答疑和新课信息:QQ交流群:422901085进行课程讨论

android跨进程通信实战视频课程(加群获取优惠)

千里马Android Framework实战开发-native程序之间binder通信实战案例分析

1、需求背景

在android系统开发中,不仅仅我们都停留在java层面,很可能也会遇到比如一些native的可执行程序,比如surfaceflinger,bootanimation等他们都是native的执行程序,这些程序之间也经常会有要进行binder跨进程通信的需求,所以这个时候学习native层进行跨进程通信是非常有必要的。

2、案例功能介绍

在app的java层面我们之前已经实现过了binder的双向通信,这里在c++层也一样来实现一个双向的binder通信
在这里插入图片描述

3、源码展示

client端:

#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 <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_SERIVCE_DES "my_hello"
#define SAMPLE_CB_SERIVCE_DES "android.os.SampleCallback"
#define SRV_CODE 1
#define CB_CODE 1
class SampeCallback : public BBinder
{
public:
  SampeCallback()
  {
    ALOGE("Client ------------------------------ %d",__LINE__);
    mydescriptor = String16(SAMPLE_CB_SERIVCE_DES);
  }
  virtual ~SampeCallback() {
  }
  virtual const String16& getInterfaceDescriptor() const{
    return mydescriptor;
  }
protected:

  void callbackFunction(int val) {
    ALOGE(" -----------callback Client ok------------------- %d val = %d",__LINE__,val);
  }

  virtual status_t onTransact( uint32_t code, const Parcel& data,Parcel* reply,uint32_t flags = 0){
    ALOGD( "my_hello 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 CB_CODE:
      //1.读取int32类型数据
      val_1 = data.readInt32();
      val_2 = data.readInt32();
      val_3 = data.readInt32();
      //2.读取String8类型字符串;str_1.string()-->String8转换char类型数组
      str_1 = data.readString8();
      str_2 = data.readString8();
      str_3 = data.readString8();

      callbackFunction(1234567);
      break;

    default:
      return BBinder::onTransact(code, data, reply, flags);
    }
    return 0;
  }
private:
  String16 mydescriptor;
};

int main()
{
  sp<IServiceManager> sm = defaultServiceManager();
  sp<IBinder> ibinder = sm->getService(String16(SAMPLE_SERIVCE_DES));
  if (ibinder == NULL){
           return -1;
     }
     Parcel _data,_reply;
     SampeCallback *callback = new SampeCallback();
     //写入客户端的callback
     _data.writeStrongBinder(sp<IBinder>(callback));
     _data.writeInterfaceToken(String16(SAMPLE_CB_SERIVCE_DES));
     int ret = ibinder->transact(SRV_CODE, _data, &_reply, 0);
    printf("Client before joinThreadPool \n");
    IPCThreadState::self()->joinThreadPool();
    printf("Client ------------------------------ main end");
    return 0;
}


server端:


#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 "sampleService"
#define SAMPLE_SERIVCE_DES "my_hello"
#define SAMPLE_CB_SERIVCE_DES "android.os.SampleCallback"
#define SRV_CODE 1
#define CB_CODE 1

class SampleService: public BBinder {
public:
  SampleService() {
    ALOGE("my_hello Server ------------------------------ %d",__LINE__);
    mydescriptor = String16(SAMPLE_SERIVCE_DES);
  }

  virtual ~SampleService() {
  }

  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);
    switch (code) {
    case SRV_CODE:
      //读取Client传过来的IBinder对象
      callback = data.readStrongBinder();

      if(callback != NULL)
       {
         Parcel _data, _reply;
	 _data.writeInt32(1);
	 _data.writeInt32(2);
	 _data.writeInt32(3);

	 //2.String8类型
	 _data.writeString8(String8("who..."));
	 _data.writeString8(String8("are..."));
	 _data.writeString8(String8("you..."));
	 //回调客户端
         int ret = callback->transact(CB_CODE, _data, &_reply, 0);
       }
      //调用server端的
      callFunction(6666);
      break;
    default:
      return BBinder::onTransact(code, data, reply, flags);
    }
    return 0;
  }

private:
  String16 mydescriptor;
  sp<IBinder> callback;
};

int main() {
  sp<IServiceManager> sm = defaultServiceManager();
  SampleService* samServ = new SampleService();
  status_t ret = sm->addService(String16(SAMPLE_SERIVCE_DES), samServ);
  printf("server before joinThreadPool \n");
  IPCThreadState::self()->joinThreadPool( true);
  printf("server after joinThreadPool \n");
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
千里马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命令的程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值