[DEMO] Android Binder 的使用

这篇具有很好参考价值的文章主要介绍了[DEMO] Android Binder 的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考:

The Android binderfs Filesystem — The Linux Kernel documentation

前言:

Android Binder 是一种 IPC 机制,IPC 键值/标识 是一个字符串,收发双方通过 键值/标识 建立通讯路径。

Binder 是通过模板类实现的,因此使用起来并不是那么简明通俗,如果没有demo可以参考的话是需要琢磨好一阵子。

相关头文件:

//  \frameworks\native\include\binder\IInterface.h
#include <binder/IInterface.h>
//  \frameworks\native\include\binder\IBinder.h
#include <binder/IBinder.h>

重要的类:

class IInterface 

IPC 的收发双方需要约定交互接口,因此收发双方都需要通过某种方式集成这个类,一般情况下会定义一个类来继承IInterface,然后收发双方再通过类模板的方式对新定义的接口类做集成。

//  \frameworks\native\include\binder\IInterface.h
class IInterface : public virtual RefBase
{
public:
            IInterface();
            static sp<IBinder>  asBinder(const IInterface*);
            static sp<IBinder>  asBinder(const sp<IInterface>&);

protected:
    virtual                     ~IInterface();
    virtual IBinder*            onAsBinder() = 0;          //需要子类实现
};

//  \frameworks\native\libs\binder\IInterface.cpp
IInterface::IInterface() 
    : RefBase() {
}

IInterface::~IInterface() {
}

// static
sp<IBinder> IInterface::asBinder(const IInterface* iface)
{
    if (iface == nullptr) return nullptr;
    return const_cast<IInterface*>(iface)->onAsBinder();
}

// static
sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface)
{
    if (iface == nullptr) return nullptr;
    return iface->onAsBinder();
}

class BpInterface

BpInterface 是模板类,他继承自一个 IInterface 的子类,同时也继承 BBinder,如果我们实现 Binder的 Client 端,则可以使用这个类作为父类。

//  \frameworks\native\include\binder\IInterface.h
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
    explicit                    BpInterface(const sp<IBinder>& remote);

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

template<typename INTERFACE>
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
    return remote();
}

前面说到 IInterface 的 onAsBinder 为纯虚函数,这里 BpInterface 就实现了这个纯虚函数,通过调用父类 BpRefBase 的 remote() 方法返回一个 IBinder。

//  \frameworks\native\include\binder\Binder.h
class BpRefBase : public virtual RefBase
{
protected:
    explicit                BpRefBase(const sp<IBinder>& o);
    virtual                 ~BpRefBase();
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);

    inline  IBinder*        remote()                { return mRemote; }
    inline  IBinder*        remote() const          { return mRemote; }

private:
                            BpRefBase(const BpRefBase& o);
    BpRefBase&              operator=(const BpRefBase& o);

    IBinder* const          mRemote;
    RefBase::weakref_type*  mRefs;
    std::atomic<int32_t>    mState;
};

class BnInterface

BnInterface 和 BpInterface 类似,它一般用作 Binder Server 端。区别在于切换至 IBinder 角色的方法不一样,Bp是 return remote() ,Bn 是直接返回自己。

template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

template<typename INTERFACE>
inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
        const String16& _descriptor)
{
    if (_descriptor == INTERFACE::descriptor) return this;
    return nullptr;
}

template<typename INTERFACE>
inline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const
{
    return INTERFACE::getInterfaceDescriptor();
}

template<typename INTERFACE>
IBinder* BnInterface<INTERFACE>::onAsBinder()
{
    return this;
}

BnInterface 是继承自 BBinder 的,这个类规定了作为 Binder 服务端应该具备哪些特质,一般情况下我们需要重写 onTransact 函数以完成我们自己的消息处理逻辑。

class BBinder : public IBinder
{
public:
                        BBinder();

    virtual const String16& getInterfaceDescriptor() const;
    virtual bool        isBinderAlive() const;
    virtual status_t    pingBinder();
    virtual status_t    dump(int fd, const Vector<String16>& args);

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    transact(   uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
                                    void* cookie = nullptr,
                                    uint32_t flags = 0);

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
                                        void* cookie = nullptr,
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = nullptr);

    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
                                        object_cleanup_func func);
    virtual void*       findObject(const void* objectID) const;
    virtual void        detachObject(const void* objectID);

    virtual BBinder*    localBinder();

    bool                isRequestingSid();
    // This must be called before the object is sent to another process. Not thread safe.
    void                setRequestingSid(bool requestSid);

protected:
    virtual             ~BBinder();

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

private:
                        BBinder(const BBinder& o);
            BBinder&    operator=(const BBinder& o);

    class Extras;

    Extras*             getOrCreateExtras();

    std::atomic<Extras*> mExtras;
            void*       mReserved0;
};

Demo

DemoInterface.h

#include <binder/IInterface.h>

// 一定要是I 开头
class IDemo : public IInterface {

//  client use
  enum {
     MSG_1,
     MSG_2,
     MSG_3,
     MSG_CNT
  }
  //  通过虚函数强制要求client实现,client通过下面这几个函数里向server侧发送MSG,并同步等待应答
  virtual void postMSG1(int i) = 0;  //带参数,组装到 MSG 里面发送给server
  virtual void postMSG2() = 0;
  virtual int postMSG3() = 0;  //可以是有返回值的

  DECLARE_META_INTERFACE(Demo);  //对应类名 I 之后的那部分
  IMPLEMENT_META_INTERFACE(Demo,"Demo"); //实现部分
}

BpDemo.h文章来源地址https://www.toymoban.com/news/detail-546401.html

#include "DemoInterface.h"

class BpDemo : public BpInterface<IDemo> 
{
public:
   //BpInterface本身没有默认构造函数,所以只能使用唯一的一个构造函数来构造,
   //这个构造函数接受一个IBinder指针作为输入,这个IBinder指向一个Binder对象,
   //所以我们实现的其子类 BpDemo 也必须有一个接受 IBinder 指针入参的构造函数来
   //构造其父类 BpInterface, 并且需要用这个 IBinder 指针构造 BpInterface。
   //
   // 小结 : 作为client侧,需要在构造的时候就知道 server 侧对应的那个 Binder是什么,这很合理
   //
   BpDemo(const sp<IBinder>& impl)
     :BpInterface<IDemo>(impl) 
   {

   }
   virtual ~BpDemo() {;}

   //必须实现IDemo中的纯虚函数
   virtual void postMSG1(int i){
      Parcel data, replay;
      //写Binder的键值(token)
      data.writeInterfaceToken(IDemo::getInterfaceDescriptor());
      data.writeInt32(i); //写需要传输的字段

      //使用BpInterface父类的remote()方法获取BBinder对象,调用transact()传输MSG
      remote()->transact(MSG1,data,&reply);
   }

   virtual void postMSG1(){
      Parcel data, replay;
      data.writeInterfaceToken(IDemo::getInterfaceDescriptor());
      remote()->transact(MSG2,data,&replay,IBinder::FLAG_ONEWAY); //异步
   }

   virtual int postMSG3(){
      Parcel data, replay;
      data.writeInterfaceToken(IDemo::getInterfaceDescriptor());
      remote()->transact(MSG3,data,&replay);
      int ret;
      reply.readInt32(ret);    //
      return ret;
   }

}


/*
BpInterface<IDemo> 展开为

class BpInterface : public IDemo, public BpRefBase
{
public:
    explicit         BpInterface(const sp<IBinder>& remote);

protected:
    typedef IDemo           BaseInterface;
    virtual IBinder*        onAsBinder();
};
*/

到了这里,关于[DEMO] Android Binder 的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 13(T) - binder阅读(3)- binder相关的类

    原先准备在binder阅读(3)中记录ServiceManager的使用,但是写着写着发现,如果不了解和binder相关的类,那么阅读起来将会由很多困惑,所以就先来记录binder相关的类了。记录完发现特别凌乱…先就这样吧。 从 binder阅读(1)一开始的图中可以看到, getService 获得的是一个han

    2024年02月11日
    浏览(28)
  • 【Android】深入Binder拦截

    ☞ Github ☜ ☞ Gitee ☜ Binder 作为 Android 系统跨进程通信的核心机制。网上也有很多深度讲解该机制的文章,如: Android跨进程通信详解Binder机制原理 Android系统核心机制Binder【系列】 这些文章和系统源码可以很好帮助我们理解Binder的实现原理和设计理念,为拦截做准备。借助

    2024年02月03日
    浏览(29)
  • Android Binder小结

    Binder是Android中一种跨进程通信方式,Binder也是一个虚拟设备,对于客户端来说Bidner是一个可以跨进程通信的一个类 Android底层是Linux,但是Linux已有的跨进程通信方式都不能满足Android移动设备的需求,在Android中跨进程通信方式,要求是CS的一对多的架构、需要保证安全,并且

    2023年04月08日
    浏览(27)
  • Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

    前面几篇文章,为我们学习Binder IPC通信机制提供了扎实的理论基础,接下来将正式进入Binder IPC通信架构及原理的解读。 Binder 是基于 C/S 架构的,由一系列的组件组成,包括 Client进程、Server进程、Service Manager进程、Binder 驱动。其中 Client进程、Server进程、Service Manager进程运行

    2023年04月09日
    浏览(33)
  • 浅谈 Android Binder 监控方案

    在 Android 应用开发中,Binder 可以说是使用最为普遍的 IPC 机制了。我们考虑监控 Binder 这一 IPC 机制,一般是出于以下两个目的: 卡顿优化:IPC 流程完整链路较长,且依赖于其他进程,耗时不可控,而 Binder 调用本身通常又是以 RPC 形式对外提供能力的,使得我们在使用时更容

    2024年02月11日
    浏览(64)
  • Android 基础技术——Binder 机制

    笔者希望做一个系列,整理 Android 基础技术,本章是关于Binder 机制 什么是Binder 机制:Binder 是一种进程间通信机制 驱动:Binder 是一个虚拟物理设备驱动 应用层:Binder 是一个能发起通信的 Java 类 为什么要使用Binder 图解析: 性能上:  binder小于共享内存 优于其他ipc 共

    2024年02月19日
    浏览(27)
  • Android 面试笔记整理-Binder机制

    作者:浪人笔记 面试可能会问到的问题 从IPC的方式问到Binder的优势 为什么zygote跟其他服务进程的通讯不使用Binder Binder线程池和Binder机制 等等这些问题都是基于你对Binder的理解还有对其他IPC通讯的理解 IPC方式有多少种 传统的IPC方式有Socket、共享内存、管道、信号量等 安卓

    2024年02月12日
    浏览(29)
  • Android Binder通信原理(一):简介

    源码基于: Android R 在Linux 系统中现有的进程间通信(IPC)方式: 管道(PIPE): 在创建时分配一个page大小的内存,缓存区大小比较有限; 命名管道(FIFO): 考虑 PIPE_BUF 和原子操作; 消息队列: 信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信; 共享内存:  无须

    2024年02月10日
    浏览(27)
  • Android Framework——Binder 监控方案

    作者:低性能JsonCodec 在 Android 应用开发中,Binder 可以说是使用最为普遍的 IPC 机制了。我们考虑监控 Binder 这一 IPC 机制,一般是出于以下两个目的: 卡顿优化:IPC 流程完整链路较长,且依赖于其他进程,耗时不可控,而 Binder 调用本身通常又是以 RPC 形式对外提供能力的,

    2024年02月04日
    浏览(26)
  • [Android 13]Binder系列--获取服务

    获取服务 hongxi.zhu 2023-7-8 以 SurfaceFlinger 进程中获取 InputFlinger 服务为例 frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 获取到SM的代理对象之前的文章已经分析过,请参考前面的:Binder系列–获取ServiceManager BpServiceManager::getService remote()从前面可知是SM的BpBinder对象,获取到SM的

    2024年02月13日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包