Binder机制,从Java到C (7. Native Service)

1.什么是NativeService

Native Service,是通过C或C++代码写出來,提供给Java进行远程调用的RemoteService。向Android开机就启动的surfaceflinger,media都是native service。

在前一篇中,我們总结了Binder通信的整個流程:
Java Proxy代码走到JNI实现的BinderProxy的transact()方法之后,就直接进入到Native实现的BpBinder,然后一直通过IPCThreadState对象发送Binder消息。
而在另一个process的IPCThreadState会接收Binder消息,再通过JNI回调Java里的Stub的onTransact()方法。

 

 

2.BnXXX 和  BpXXX

如果需要通过Native代码來提供服务:
从IBinder接口的Stub对象的原理可以看出,如果在回调Java的JNI之前将代码调用截断,直接通过Native代码來实现onTransact()方法,就可以完成Service的Stub端的实现。
同時,RemoteService应该不仅提供给Java,也可以提供给Native,所以也应该提供Native的Proxy端,就是直接通过BpBinder的transact()方法來发送Binder消息。


下面图中的 BnXXX和BpXXX对应着Java环境里的的Stub和Proxy

 

 

 

3. 怎樣寫Native Service?
如果要手动实现各个类,会造成代码的大量重复,并且出错的几率会大大增加。

和Java环境里的aidl工具类似。Native也会使用重用技术。它的重用是通过template 体现的。

一些模板类都在IInterface中。

/frameworks/native/include/binder/IInterface.h

 1 class IInterface : public virtual RefBase
 2 {
 3 public:
 4             IInterface();
 5             sp<IBinder>         asBinder();
 6             sp<const IBinder>   asBinder() const;
 7 
 8 protected:
 9     virtual                     ~IInterface();
10     virtual IBinder*            onAsBinder() = 0;
11 };
12 
13 template<typename INTERFACE>
14 class BnInterface : public INTERFACE, public BBinder//实现Stub功能的模板,扩展BBinder的onTransact()方法实现Binder命令的解析和执行。
15 {
16 public:
17     virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
18     virtual const String16&     getInterfaceDescriptor() const;
19 
20 protected:
21     virtual IBinder*            onAsBinder();
22 };
23 
24 template<typename INTERFACE>
25 class BpInterface : public INTERFACE, public BpRefBase//实现Proxy功能的模板,BpRefBase里有个mRemote对象指向一个BpBinder对象。
26 {
27 public:
28                                 BpInterface(const sp<IBinder>& remote);
29 
30 protected:
31     virtual IBinder*            onAsBinder();
32 };

 

来看一下类结构:

 

 

有了template,编写一个Native Service的工作量也不大。比如如果将第一篇中的Application RemoteService 转化成Native Service:
1.实现一个接口文件,IXXXService,继承IInterface
2.定义BnXXX,继承BnInterface<IXXXService>。实现一个XXXService,继承BnXXX,并实现onTransact()函数。
3.定义BpXXX,继承BpInterface<IXXXService>。

 

如果实现了native的RemoteService,会是下面的结构。红框框就是我们要写的。

 

 

Native Service只要稍微了解一下,看得懂代码流程就好了,毕竟应该没什么机会去写native service吧。

 

 

转载于:https://www.cnblogs.com/zhangxinyan/p/3487889.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
main SpringApplication.java:771 - Application startup failed org.springframework.context.ApplicationContextException: Failed to start bean 'inputBindingLifecycle'; nested exception is org.springframework.cloud.stream.binder.BinderException: Exception thrown while starting consumer: at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:50) at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:348) at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:151) at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:114) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:880) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) at com.migu.rstone.UserCenterApplication.main(UserCenterApplication.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) Caused by: org.springframework.cloud.stream.binder.BinderException: Exception thrown while starting consumer: at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindConsumer(AbstractMessageChannelBinder.java:258) at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindConsumer(AbstractMessageChannelBinder.java:57) at org.springframework.cloud.stream.binder.AbstractBinder.bindConsumer(AbstractBinder.java:145) at org.springframework.cloud.stream.binding.BindingService.bindConsumer(BindingService.java:97) at org.springframework.cloud.stream.binding.BindableProxyFactory.bindInputs(BindableProxyFactory.java:221) at org.springframework.cloud.stream.binding.InputBindingLifecycle.start(InputBindingLifecycle.java:55) at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:175) ... 22 more Caused by: java.lang.IllegalArgumentException: A list of partitions must be provided at org.springframework.util.Assert.isTrue(Assert.java:92) at org.springframework.cloud.stream.binder.kafka.KafkaMessageChannelBinder.createConsumerEndpoint(KafkaMessageChannelBinder.java:241) at org.springframework.cloud.stream.binder.kafka.KafkaMessageChannelBinder.createConsumerEndpoint(KafkaMessageChannelBinder.java:88) at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doBindConsumer(AbstractMessageChannelBinder.java:217) ... 28 more 报错解决办法
最新发布
07-15

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值