Binder远程转本地

前言

在[031]Binder线程栈复用中,我们说到Binder驱动通过“线程栈复用”减少线程数,我们来讲一讲另外一个机制“远程转本地”,将远程Binder调用转化成本地方法调用。

一、写个Demo

interface  IServiceB {void sendMsg(String msg);
}

1.1 Client端

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获得Service B的服务Intent intent = new Intent(this, ServerB.class);this.bindService(intent, new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Log.v("KobeWang", "serviceB:" + service);IServiceB serviceB = IServiceB.Stub.asInterface(service);try {serviceB.sendMsg("hello ServiceB");} catch (RemoteException re) {}}@Overridepublic void onServiceDisconnected(ComponentName name) {}}, Context.BIND_AUTO_CREATE);}
}

1.2 Server端

public class ServerB extends Service {@Overridepublic IBinder onBind(Intent intent) {return new ServiceB();}public class ServiceB extends IServiceB.Stub {@Overridepublic void sendMsg(String msg) throws RemoteException {Log.v("KobeWang", "get msg : "  + msg);}}
}

注意android:process=":server"这个代码,后面要删除对比测试

<serviceandroid:name=".ServerB"android:exported="true"android:process=":server"></service>

二、运行结果

2.1 android:process=":server"

此时ServiceB(pid=7120)和Client端(pid=7073)运行在不同进程
Client端拿到的service是ServiceB的远程代理类BinderProxy
ServiceB响应发生pid=7120进程,响应代码也是从Binder驱动中execTransact触发的。

//Client端从Binder驱动中拿到的service是ServiceB的远程代理类BinderProxy
7073  7073 V KobeWang: serviceB:android.os.BinderProxy@4ae510
//ServiceB中响应在另一个进程
7120  7142 V KobeWang: get msg : hello ServiceB
//ServiceB中响应代码堆栈也是从Binder.execTransact开始,Binder驱动触发
7120  7142 V KobeWang: java.lang.Exception: KobeWang
7120  7142 V KobeWang:  at com.kobe.binderlock.ServerB$ServiceB.sendMsg(ServerB.java:20)
7120  7142 V KobeWang:  at com.kobe.binderlock.IServiceB$Stub.onTransact(IServiceB.java:61)
7120  7142 V KobeWang:  at android.os.Binder.execTransactInternal(Binder.java:1035)
7120  7142 V KobeWang:  at android.os.Binder.execTransact(Binder.java:1008)

2.2 删除android:process=":server"之后

此时ServiceB和Client端运行在同一进程(pid=7384)
Client端拿到的service直接是ServiceB的这个类(继承Binder)
响应代码堆栈就像是直接调用ServiceB的sendMsg方法。

//Client端从Binder驱动中拿到的service就是ServiceB这个类
7384  7384 V KobeWang: serviceB:com.kobe.binderlock.ServerB$ServiceB@1778355
//ServiceB中响应在同一个进程的同一线程
7384  7384 V KobeWang: get msg : hello ServiceB
//ServiceB中响应代码堆栈好像是直接调用ServiceB的sendMsg的方法。
7384  7384 V KobeWang: java.lang.Exception: KobeWang
7384  7384 V KobeWang:  at com.kobe.binderlock.ServerB$ServiceB.sendMsg(ServerB.java:20)
7384  7384 V KobeWang:  at com.kobe.binderlock.MainActivity$1.onServiceConnected(MainActivity.java:28)
7384  7384 V KobeWang:  at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1948)
7384  7384 V KobeWang:  at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1980)
7384  7384 V KobeWang:  at android.os.Handler.handleCallback(Handler.java:883)
7384  7384 V KobeWang:  at android.os.Handler.dispatchMessage(Handler.java:100)
7384  7384 V KobeWang:  at android.os.Looper.loop(Looper.java:214)
7384  7384 V KobeWang:  at android.app.ActivityThread.main(ActivityThread.java:7501)
7384  7384 V KobeWang:  at java.lang.reflect.Method.invoke(Native Method)
7384  7384 V KobeWang:  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
7384  7384 V KobeWang:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

三、总结

大家看明白了吧,这就是Binder远程转本地的机制,一个Binder对象同一个进程中拿到的是Binder对象本身,另一个进程中拿到的是BinderProxy代理类,跨进程调用也就变成了本地方法调用,提升Binder通信效率。

上面是两个进程,这个机制适用于多个进程传递同一个Binder对象。

进程A将Binder A通过Binder方法传递给进程B,进程B拿到的是BinderProxy A
进程B又将BinderProxy A通过Binder方法传递给进程C,进程C拿到的还是BinderProxy A
进程C将BinderProxy A通过Binder方法传递给进程A,进程A拿到的却是Binder A


记住一句话
一个IBinder对象(Binder或者BinderProxy)通过Binder方法传递的时候,Binder驱动就会校验远程转本地这个机制。如果发现这个IBinder对象的服务端(Binder)定义在本进程,就直接返回Binder对象,否则返回BinderProxy对象。

四、思考

AIDL oneway的这个标识符是不是在Binder远程转本地的时候,是不是也就失去了意思?
面试官问你:Binder服务端oneway方法sleep10秒,是否会导致client端sleep10秒?
你应该知道怎么回答了吧。

  回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467911.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

存储对手机性能的影响

前言几年以前&#xff0c;我被派去厦门上门去分析一个用户的手机卡顿问题&#xff0c;该用户的手机经常莫名无响应&#xff0c;刷机&#xff0c;恢复出厂都没有用&#xff0c;经过一通分析&#xff0c;原来该用户从熟人店里买到了一张盗版的SD卡&#xff08;这年头坑的就是朋友…

进阶攻略|前端最全的框架总结

前端的技术日渐更新&#xff0c;最近得空&#xff0c;花了一上午的时间&#xff0c;将前端常见的UI框架总结了一下&#xff0c;在开发的过程之中&#xff0c;有了这些&#xff0c;不断能够提高自己的工作效率&#xff0c;还可以在工作之余了解更多。希望大家喜欢。1.Layui官方网…

你知道char *s和char s[]的区别吗?

在一个夜深人静的晚上&#xff0c;有一个读者给我发了一个C语言题目。他问我&#xff0c;发哥&#xff0c;帮我看看这个代码有什么问题。我看了代码之后&#xff0c;心里一阵恐慌。我自认为我不是C语言高手。但我确实是一个喜欢解决问题的男人。就是在这样的背景驱使下&#xf…

上Google Adsense个人的一点体验

最近我想开通一个Google Adsense帐号&#xff0c;因为以前注册过一个Google帐号&#xff0c;所以我以为两个是可以共通的&#xff0c;因为很久没上Google帐号&#xff0c;我记不太清密码了&#xff0c;所以我先是登录了Google&#xff0c;登上去了&#xff0c;密码没记错。然后…

通俗易懂,嵌入式Linux驱动基础

前言上一篇分享的&#xff1a;《从单片机工程师的角度看嵌入式Linux》中有简单提到Linux的三大类驱动&#xff1a;我们学习编程的时候都会从hello程序开始。同样的&#xff0c;学习Linux驱动我们也从最简单的hello驱动学起。驱动层和应用层 还记得实习那会儿我第一次接触嵌入式…

记,我在深圳买房

今天晚上&#xff0c;有点时间&#xff0c;把这次买房的经历写下来。我并不是想炫耀&#xff0c;也不是想说明什么&#xff0c;只是为了记录自己的生活。这是对自己的一个阶段性总结&#xff0c;也希望自己的意见和想法对读者们有些帮助。再者&#xff0c;凭自己的努力&#xf…

tif 高程_使用ArcGIS提取高程点

地球表面形状的最常见数字化数据便是基于像元的数字高程模型(DEM)&#xff0c;该数据可用作量化地表特征的输入。DEM属于一种连续表面的栅格制图表达&#xff0c;通常参考真实的地球表面&#xff0c;有的时候除了需要DEM还需要高程点&#xff0c;这里讲解一下如何使用ArcGIS从D…

你试试用心呼吸

我曾经历过掉水里&#xff0c;两次。第一次&#xff0c;是在水上乐园&#xff0c;不会游泳的我&#xff0c;从高滑梯上头朝下扎到水中。一下子&#xff0c;就感觉呼吸不了&#xff0c;非常惊恐&#xff0c;然后有人&#xff08;救生员&#xff09;揽住了我&#xff0c;我非常惊…

Git安装及密钥的生成并上传本地文件到GitHub上

之前用的GitHub&#xff0c;不太熟练&#xff0c;一直在上传的过程中遇到了一些问题&#xff0c;看了网上诸多教程&#xff0c;总觉得很乱&#xff0c;特参考一些资料&#xff0c;总结了一篇完整的操作步骤&#xff0c;从下载安装到上传文件&#xff0c;亲测有效1.下载Git软件&…

声明为数组定义为指针,声明为指针定义为数组

导语在这里我们做种强调的是在两个文件中&#xff0c;定义为数组声明为指针和定义为指声明为数组的这辆中情况。那么我们就需要两个源文件test.c和main.c。定义为数组&#xff0c;声明为指针test.cchar arr[] "abcdef";main.c#define _CRT_SECURE_NO_WARNINGS 1 #in…

python selenium环境配置Firefox和Chrome

1、下载Selenium库&#xff0c;可以使用pip install selenium https://pypi.python.org/pypi/selenium/ 2、下载驱动 Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads Firefox: https://github.com/mozilla/geckodriver/releases 3、配置环境变量 需要…

BUG_ON()、panic()、dump_stack()几种内核调试手段

Linux内核有一些方法可以用来方便标记bug&#xff0c;提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。当被调用的时候&#xff0c;它们会引发oops&#xff0c;导致栈的回溯和错误信息的打印。这些声明会导致 oops跟硬件的体系结构是相关的。大部分体系结构把BUG()和BUG_O…

wordvba编程代码大全_这几本基础编程书籍一定要看

程序员书库(ID&#xff1a;OpenSourceTop) 编译书单来自&#xff1a;https://simpleprogrammer.com/best-programming-books-2019/关于程序员类的技术书籍有很多&#xff0c;但是往往没有时间阅读&#xff0c;下面的这些书籍&#xff0c;由John Sonmez精选&#xff0c;可以帮助…

经典DP

1.背包问题 &#xff08;1&#xff09;01背包 从n个重量和价值分别为wi,vi的物品&#xff0c;从中选出不超过W的物品&#xff0c;每种物品仅有一件&#xff0c;求所有方案中V的最大值。 最朴素最简单也最费时的方法&#xff1a;O(2^n) int rec(int i,int j)//从第i个开始挑选总…

C语言、嵌入式重点知识:回调函数

前言 上文分享了一个专用的双链表的基本操作示例&#xff1a;双链表的操作示例&#xff08;附代码&#xff09;这里提到了一个关键词&#xff1a;专用。与专用对应的词是通用。我们从字面上可以很容易理解这两个词&#xff0c;专用就是针对特定情况的&#xff0c;特点就是很有局…

今天我勇敢的点就一个gpio口

现在已经三月份了&#xff0c;时间过得超快&#xff0c;早上起来打开电脑&#xff0c;有点不习惯&#xff0c;微信群唧唧歪歪的那些股神今天不知为什么安静了。我喜欢看大家热闹的样子&#xff0c;更喜欢热闹的时候给我们发几个红包。我记得2015年&#xff0c;股市非常好&#…

数据结构(4)

文章目录栈与队列栈队列![在这里插入图片描述](https://img-blog.csdnimg.cn/20200301182116946.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzY2Mzc4MA,size_16,color_FFFFFF,t_70)栈与队列 栈 ha…

写一个公用的gpio口驱动

因为项目需要控制的GPIO口比较多&#xff0c;如果每个GPIO口都写一个驱动就显得比骄麻烦&#xff0c;所以就写了一个通用的GPIO口驱动。只要dts里面配置好设备GPIO相关信息就可以自动加载了。可以很充分的体现多个设备一个驱动的优良性。dts文件gpio_rs485: gpio_rs485 {status…

数据结构(5)

文章目录各种算法选择排序插入排序希尔排序***快速排序***归并排序二分查找各种算法 def bubble_sort(alist):"""冒泡排序"""n len(alist)for j in range(n-1):count 0for i in range(0, n-1-j):# 班长从头走到尾if alist[i] > alist[i1]:a…

大神们都应该去哪里工作?

接上一篇文章。文中提到我认识了一个做嵌入式的大神&#xff0c;技术真的非常厉害。我们在调试过程中&#xff0c;遇到问题&#xff0c;他总是能告诉我们排查的手段&#xff0c;而且针对一个问题&#xff0c;他能想到几种不同的解决方案。嵌入式驱动跟其他软件有点不一样&#…