如何在Android下使用Binder

2025-03-21 23:42:40
推荐回答(2个)
回答1:

 实现一个binder通信实例,需要经过以下步骤:
  (1)获得ServiceManager的对象引用

  (2)向ServiceManager注册新的Service

  (3)在Client中通过ServiceManager获得Service对象引用

  (3)在Client中发送请求,由Service返回结果。

  下面看具体的代码如何实现。

  3.1 libmyservice代码实现

  (1)新建目录frameworks/base/myservice/libservice,进入该目录

  view plain
  $ cd frameworks/base
  $ mkdir myservice
  $ cd myservice
  $ mkdir libmyservice
  $ cd libmyservice

  (2)编写libmyservice/myservic.h文件

  view plain
  #include
  
  #include
  
  #include
  
  #include
  
  #include
  
  
  
  namespace android {
  
  class MyService : public BBinder
  
  {
  
  mutable Mutex mLock;
  
  int32_t mNextConnId;
  
  public:
  
  static int instantiate();
  
  MyService();
  
  virtual ~MyService();
  
  virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
  
  };
  
  }; //namespace

  (2)编写libservice/myservice.cpp文件

  view plain
  #include "myservice.h"
  
  #include
  
  #include
  
  
  
  namespace android {
  
  
  
  static struct sigaction oldact;
  
  static pthread_key_t sigbuskey;
  
  
  
  int MyService::instantiate()
  
  {
  
  LOGE("MyService instantiate");
  
  // defaultServiceManager ()获得ServiceManager的对象引用,addService()可向ServiceManager注册新的服务
  
  int r = defaultServiceManager()->addService(String16("android.myservice"), new MyService());
  
  LOGE("MyService r = %d/n", r);
  
  return r;
  
  }
  
  
  
  MyService::MyService()
  
  {
  
  LOGV("MyService created");
  
  mNextConnId = 1;
  
  pthread_key_create(&sigbuskey, NULL);
  
  }
  
  
  
  MyService::~MyService()
  
  {
  
  pthread_key_delete(sigbuskey);
  
  LOGV("MyService destroyed");
  
  }
  
  // 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数,该函数分析接收到的数据包,调用相应的接口函数处理请求
  
  status_t MyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
  
  {
  
  switch(code)
  
  {
  
  case 0: {
  
  pid_t pid = data.readInt32();
  
  int num = data.readInt32();
  
  num = num + 100;
  
  reply->writeInt32(num);
  
  return NO_ERROR;
  
  }
  
  break;
  
  default:
  
  return BBinder::onTransact(code, data, reply, flags);
  
  }
  
  }
  
  }; //namespace

  (3)编写libservice/Android.mk文件

  view plain
  # File: Android.mk
  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  LOCAL_SRC_FILES := myservice.cpp
  LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
  LOCAL_SHARED_LIBRARIES := libutils libbinder
  LOCAL_MODULE_TAGS := optional
  LOCAL_PRELINK_MODULE := false
  LOCAL_MODULE := libmyservice
  
  include $(BUILD_SHARED_LIBRARY)

  (4)编译libmyservice.so动态库

  在android源码主目录下

  view plain
  $ source build/envsetup.sh
  
  including device/htc/passion/vendorsetup.sh
  
  including device/samsung/crespo4g/vendorsetup.sh
  
  including device/samsung/crespo/vendorsetup.sh
  
  
  $ mmm frameworks/base/myservice/libmyservice/

  编译成功后生成文件:out/target/product/generic/system/lib/libmyservice.so

回答2:

Binder是基于OpenBinder,在Android系统上使用的进程间通信机制。

Binder基于Client-Server通信模式,本质上可以理解为它实现了Client对Server对象的远程调用。比如,有某个binder对象A位于Server中,该对象提供了一套函数用以实现对服务的请求,而在一个或多个Client中包含对象A的引用,Client通过该引用可以调用远端Server中对象A的接口函数,这种远端调用对Client而言,与调用本地对象并无区别。
Binder机制定义了四个组件,分别是Client,Server,ServiceManager和binder驱动,其中Client,Server,ServiceManager运行于用户空间,binder驱动运行于内核空间。
binder驱动是内核中的一个字符设备驱动/dev/binder,它是整个Binder通信机制的核心。Client,Server,ServiceManager通过open()和ioctl()文件操作函数与binder驱动进行通信,从而实现了Client向Server发送请求,Server处理请求并返回结果到Client。具体来说,它负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
ServiceManager是一个守护进程,负责管理服务,即所有的Server需要向ServiceManager注册服务。同时,ServiceManager向Client提供查询和获取Server的接口。
实现一个binder通信实例,需要经过以下步骤:

(1)获得ServiceManager的对象引用

(2)向ServiceManager注册新的Service

(3)在Client中通过ServiceManager获得Service对象引用

(3)在Client中发送请求,由Service返回结果。