android binder机制之--(创建binder服务)

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)客户端获取服务代理对象

客户端进程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)客户端调用服务端函数

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

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

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

到这里,我们已经把android中的binder机制介绍完了。呵呵,本来觉得binder机制总结起来不会很难,可在写总结的过程中还是遇到了很多问题。呵呵,不过还好,都差不多一一解决了,终于写完了。总结过程中相当于又学了一边binder机制,而且还有新的收获,真的不错哦!

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. Android(安卓)TabHost学习笔记
  4. Android高手进阶教程(三)之----Android(安卓)中自定义View的应用
  5. 代码讲解Android(安卓)Scroller、VelocityTracker
  6. Android电源管理
  7. android面试题总结—摘自csdn
  8. 学习笔记| (二)IPC机制
  9. Android(安卓)中自定义控件和属性(attr.xml,declare-styleable,T

随机推荐

  1. 从某人的公众号学到一个网上学习资源搜索
  2. 一文读懂HTTP常见状态码
  3. 视频播放如何更安全流畅?看南非影音娱乐DS
  4. JavaEE面试题总结,一篇文章带你攻克面试难
  5. java使用 Cookie 和 JWT 身份验证
  6. SSM三大框架整合详细教程(Spring+SpringMV
  7. 深陷低效内耗,没有哪家企业是无病呻吟
  8. 短信接口怎么对接?看完这篇文章你就知道了
  9. web前端开发必备技能
  10. 前端工程师想要做一个Vue-ts后台管理系统