前言

在[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学习资料

Binder远程转本地相关推荐

  1. 查询远程或本地计算机的登录账户

    用下面这个函数能获取远程或本地电脑的当前登录用户,同时附加了它的计算机名,所以当你查询多台电脑时将知道结果从哪里来. function Get-LoggedOnUser {param([String[ ...

  2. php ssh 管理服务器,php 利用ssh执行远程或本地liunx服务器命令

    /** * 利用ssh执行 远程或本地liunx服务器命令 * 虽然可以用 shee_exec来执行本地机命令 但却无法选择用哪个用户来执行 此函数可解决此类问题 * $host ssh 主机名 可以 ...

  3. Linux 远程和本地的一些解决方案

     有的小伙伴想Linux 远程登录 两台机器同时root登录,其实可以同时多个用户的. Linux是多用户的多任务系统,可以同时多个用户登录到系统,也可以一个用户通过不同终端登录到一个系统执行不同的操 ...

  4. java远程连接fpt_java远程连接本地fpt

    java远程连接本地fpt [2021-02-07 17:48:19]  简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace("/ ...

  5. Xshell远程登录本地虚拟机(保姆级教学)

    前言 最近在学习Liunx,正好学习到利用Xshell7进行远程登录时,苦于视频中教学不够清晰,参考网上一些教学,弄了好久,才搞定的.有人说连接本地只能使用桥接,其实不然,也是能够使用Net模式而且可 ...

  6. 云主机远程调用本地USB设备

    本文适用于远程连接本地加密狗.打印机.U盘.身份认证设备等几乎所有USB设备,也适用于本地局域网内共USB设备, 不过要是远程连接存储设备用途,现实点骚年们,在没有校验算法和断点续传的协议下传输较大文 ...

  7. 云服务器Winodws 远程连接映射本地电脑磁盘

    云服务器Winodws 远程连接映射本地电脑磁盘 打开电脑左下方 开始 - 所有程序 - 附件 - 远程桌面连接,连接服务器时勾选本地磁盘映射,如下截图所示: 然后输入 服务器IP,账号密码登陆到服务 ...

  8. k3如何作为无线打印服务器,k3远程服务器本地打印

    k3远程服务器本地打印 内容精选 换一换 打开浏览器,在地址栏输入https://部署服务器的ip:端口号(例如:https://10.175.34.143:8082)登录时跳转其他界面或者登录等操作 ...

  9. Java调用打印机打印(远程、本地皆可用)

    Java调用打印机打印(远程.本地皆可用) 背景 准备 MAVEN环境 步骤 获取PrinterJob 设置PrinterJob纸张样式 打印PDF 背景 开发个Java项目需要远程调用共享打印机打印 ...

最新文章

  1. act转MP3格式工具
  2. python在化学方面的应用-python化学库
  3. [Swift]LeetCode649. Dota2 参议院 | Dota2 Senate
  4. javascript常用排序算法总结
  5. C:输入数字计数(数组方法)
  6. 使用Spring Data MongoDB和Spring Boot进行数据聚合
  7. Exchange安装过程中经常遇到的服务器需要重启问题
  8. atlas 200 远程图形化桌面
  9. SQL Server触发器创建、删除、修改、查看
  10. servlet处理多个请求 笔记
  11. WebService高级,可靠消息
  12. 详细关闭iiop方法_安卓手机卡顿清理垃圾是没用的,教你关闭几个设置,告别手机迟钝...
  13. 32位xp系统识别4G以上内存
  14. html a3纸大小,A3和A4的纸大小都是多大的?
  15. 适用于高速公路的查询软件,数据稳定、免维护,可查询高速路况、路线规划、未来天气等信息
  16. ARIMA模型的拖尾截尾问题
  17. Web全栈架构师(三)——NodeJS+持久化学习笔记(2)
  18. NVDIMM在闪存存储中的应用探讨
  19. ffmpeg命令行,单张图片,音频合成视频
  20. 如何在微软Azure上搭建个人博客网站

热门文章

  1. MySQL 性能监控 4 大指标
  2. iPhone开发笔记[1/50]:初学iPhone上用Quartz 2D画图
  3. 笔记本 cpu 参数
  4. 部署WSE3.0实战:性能、证书与WSE910错误
  5. FMStocks7 , 不错的一个.NET 示例程序
  6. 网络爬虫--17.【BeautifuSoup4实战】爬取腾讯社招
  7. {%extends bootstrap/base.html%}的添加,使得其他block无法继承
  8. python 对象序列化 pickling_python操作文件——序列化pickling和JSON
  9. grid autosport额外内容下载慢_清理大王app下载-清理大王v1.0安卓下载
  10. java comparator排序顺序_Java 集合排序策略接口 Comparator