Binder机制编程

前面的几篇文章具体介绍了android中binder机制的方方面面,相信你对binder机制已经有了较深刻的理解。俗话说得好“学以致用”,以下我们就通过在android系统中创建一个我们自己的binder服务,来加深对binder机制的理解。

(1)增加新建的服务名称

在service_manager.c文件里有一个结构数组allowed,在allowed结构体数组中增加新建的服务名称

static struct {
    unsigned uid;
    const char *name;
} allowed[] = {
#ifdef LVMX
    { AID_MEDIA, "com.lifevibes.mx.ipc" },
#endif
    { AID_MEDIA, "media.audio_flinger" },
    { AID_MEDIA, "media.player" },
    { AID_MEDIA, "media.camera" },
    { AID_MEDIA, "media.audio_policy" },
    { AID_RADIO, "radio.phone" },
    { AID_RADIO, "radio.sms" },
    { AID_RADIO, "radio.phonesubinfo" },
    { AID_RADIO, "radio.simphonebook" },
/* TODO: remove after phone services are updated: */
    { AID_RADIO, "phone" },
    { AID_RADIO, "isms" },
    { AID_RADIO, "iphonesubinfo" },
{ AID_RADIO, "simphonebook" },
 
{AID_NEW, "newservice"}
};
 

(2)定义ImyService类

定义一个继承自IInterface的接口类,须是以大写字母I開始,以IMyService为例接口函数必须为纯虚函数,以便在子类中生产,在定义接口时将DECLARE_META_INTERFACE宏放进接口类定义中,这个宏的最重要作用是将代理对象BpBinder转化成本地封装的服务代理对象(在这里是BpMyService对象),代码大致例如以下:

Class ImyService:public IInterface
{
Public:
    DECLARE_META_INTERFACE(MyService);
        
    Virtual fun1() = 0;
    Virtual fun2() = 0;
}

 

(3)定义一个本地实现类BnMyService

在IMyService.h头文件里定义接口实现类BnMyService, 需继承自BnInterface,间接双继承了IMyService接口类和BBinder类,代码例如以下:

Class BnMyService:public BnInterface<IMyService>
{
Public:
    Virtual status_t onTransact(uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
}

(4)定义本地代理类BpMyService

在IMyService.cpp源文件里,定义接口代理类BpMyService,需继承自BpInterface。BpMyService能够提供IMyService接口所定义的接口函数。

class BpMyService: public BpInterface<IMyService>
{
public:
    BpMyService(const sp<IBinder>& impl)
        : BpInterface<IMyService>(impl)
    {
}
void fun1()
    {
        Parcel data, reply;
        ……            //数据写入
        remote()->transact(枚举量, data, &reply);
        return ……     //数据返回
    }
……
}

(5)增加宏定义

在IMyService.cpp源文件里,增加宏定义IMPLEMENT_META_INTERFACE()

 
IMPLEMENT_META_INTERFACE(MyService, "XXX");
 

(6)定义BnMyService的onTransact()函数

在IMyService.cpp源文件里实现接口实现类BnMyService,当中onTrasact()函数依据功能代码枚举量的不同分别运行不同的功能调用。

status_t BnMyService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {      //code功能代码枚举量
        case功能代码枚举量: {
            LOGV("NOTIFY_CALLBACK");
            CHECK_INTERFACE(ICameraClient, data, reply);    //检查描写叙述符字符串
            ……        //參数输入,接口函数功能的真正实现
            reply->……);   //返回数据
            return NO_ERROR;
        } break;
……
default:
            return BBinder::onTransact(code, data, reply, flags);
}

(7)创建真正的本地接口实现类MyService类

在头文件里定义类MyService,继承自BnInterface,定义功能函数和初始化函数instantiate():

Class MyService:public BnMyService
{
Public:
    Static void instantiate();
    
    Virtual func1();
    Virtual func2();
    ……
}
 

(8)定义MyService::instantiate()函数

void MyService::instantiate() {
    defaultServiceManager()->addService(
            String16("newservice"), new MyService());
}
    

(9)服务进程中注冊服务

在服务进程A初始化时增加MyService:: instantiate()函数,注冊服务,调用joinThreadPool()函数进入循环等待调用,侦听请求、处理请求。

int main(int argc, char** argv)
{
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    LOGI("ServiceManager: %p", sm.get());
    MyService::instantiate();
    ……
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

(10)client获取服务代理对象

client进程B要想和服务端通讯,首先须要获取服务管家ServiceManager的代理对象,,然后查找服务,由于服务已经注冊,所以会返回一个该服务代理对象的引用,此代理对象中包括一个指向查找的服务的handle句柄。

const sp<IMyService>& MyServiceSystem::get_MyService()
{
    Mutex::Autolock _l(mLock);
    if (gMyService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();    //获取服务管家的代
//理对象
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16("newservice")); //查找到服务后,
//返回服务的代理对象
            ……
        } while(true);
        ……
        gMyService = interface_cast<IMyService>(binder);    //将其转换为本地服
//务代理对象(BpMyService)
        ……
    }
    ……
    return mMyService;
}

(11)client调用服务端函数

client进程B调用IMyService的接口函数,调用会传递给包括了服务对象handle的代理对象BpBinder,写入binder内核驱动。binder驱动知道数据传递到的对象,于是将数据传递给进程A。

服务端进程A从binder驱动中读取数据,然后处理远程调用,然后发送reply数据给binder驱动。binder驱动将reply传递给client进程B。进程B从binder驱动中读取数据并最终获取到reply,从而完毕进程通信。

Status_t MyServiceSystem::func1()
{
    Const sp<IMyService>& af = MyServiceSystem::get_MyService();
    Af::Func1();
    ……
}

到这里,我们已经把android中的binder机制介绍完了。呵呵,本来认为binder机制总结起来不会非常难,可在写总结的过程中还是遇到了非常多问题。呵呵,只是还好,都差点儿相同一一攻克了,最终写完了。总结过程中相当于又学了一边binder机制,并且还有新的收获,真的不错哦!

android binder机制之——(创建binder服务)相关推荐

  1. Android Binder机制(二) ------- 服务的实现

    服务分析 所谓服务,简单点就是不断的监听客户端的请求,然后处理并向客户端返回处理的结果.要实现这一功能,至少需要以下几点: 循环,我们的服务就是一个大循环,不断的监听客户发来的请求.(线程循环) 通讯 ...

  2. Android 进阶8:进程通信之 Binder 机制浅析

    读完本文你将了解: IBinder Binder Binder 通信机制 Binder 驱动 Service Manager Binder 机制跨进程通信流程 Binder 机制的优点 总结 Than ...

  3. 一文分析Binder机制和AIDL的理解

    为什么要去理解Android的进程间通信机制 对于Android开发工程师来说,如果不去理解进程间通信机制也可以使用系统提供的API完成应用开发,但如果想要达到更高的层级,那么就不能简单只会调用API ...

  4. 【Binder 机制】进程通信 | 用户空间与内核空间 | MMU 与虚拟内存地址

    文章目录 一.进程通信 二.用户空间与内核空间 三.MMU 与虚拟内存地址 一.进程通信 进程隔离概念 : 系统中的进程存在 " 进程隔离 " , 出于对进程运行的保护 , 两个进 ...

  5. Android Binder机制:编写自己的本地服务

    原址 前面几篇博客中系统地介绍了本地服务的注册.检索以及使用过程.这篇博客我们将完成一个属于自己的本地服务:AllenService. 由前面的学习知道,要完成一个自己的本地服务,需要有IAllenS ...

  6. 理解 Android 的 Binder 机制

    Binder机制的工作流程 1.客户端获取服务端的代理对象(proxy).我们需要明确的是客户端进程并不能直接操作服务端中的方法,如果要操作服务端中的方法,那么有一个可行的解决方法就是在客户端建立一个 ...

  7. aidl使用_借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉

    AIDL 是 Android Interface Definition Language(Android 接口定义语言)的缩写,它是 Android 进程间通信的接口语言.由于 Android 系统的 ...

  8. Android深入浅出之Binder机制

    Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的.所以搞明白B ...

  9. 理解Android Binder机制(3/3):Java层

    本文是Android Binder机制解析的第三篇,也是最后一篇文章.本文会讲解Binder Framework Java部分的逻辑. Binder机制分析的前面两篇文章,请移步这里: 理解Andro ...

最新文章

  1. 爬虫之Xpath详解
  2. 秒拨动态ip切换技术python_Python爬虫如何通过更换IP避开网站的反爬虫机制(一)...
  3. 甘特图 知乎_安利!拥有这5款甘特图工具,项目管理、生产排程轻松搞定!
  4. 傅里叶变换处理音频c++_KWS-SoC——基于Wujian100的音频流关键词检测SoC拓展开发笔记之一...
  5. Oracle分析函数三——SUM,AVG,MIN,MAX,COUNT
  6. 领域驱动设计和开发实战总结
  7. Linux学习笔记-调用pthead_create创建线程
  8. flex3 接受外部参数
  9. li标签之间的空隙问题(转)
  10. Python+django网页设计入门(17):模板语法及应用
  11. CCF201409-3 字符串匹配(解法二)(100分)(废除!!!)
  12. 用vs2012的命令利用xsd文件生成对应的C#类,把xml的string类型映射到生成的类
  13. utools插件合集 v1.3.5绿色版
  14. 世嘉MD游戏开发【十二】:伪3D地面,Pseudo-3D
  15. macOS连接ftp服务器
  16. 初学者:html中的表单详解(下面附有代码)
  17. MobaXterm SSH 保持连接
  18. 发明专利、实用新型专利、外观设计专利
  19. 洛谷P2298 Java解法
  20. 算法:Smith数问题

热门文章

  1. echarts的词云图表类型有哪些_词云图的几种制作方法评测,你pick哪款
  2. 什么叫安装文件索引服务器,搜出精彩 玩转Windows 2008系统心得
  3. wrs-tuya-cloud
  4. glibc降级后怎么恢复 linux_Linux(CentOS)GLIBC出错补救方式
  5. 怎樣制作线段动画_PPT动画还能这么做?我擦!动画源文件免费送你
  6. swift中单例的创建及销毁
  7. HTML超出部分滚动效果 HTML滚动 HTML下拉 附效果图
  8. iOS UIButton 文字图片上下左右布局
  9. 深度分析Java的枚举类型——枚举的线程安全性及序列化问题
  10. 从 Java 到 Scala(二):object