Messenger: 基于消息的 跨进程通信(完结)

基于 Handler 的 IPC 进程间通信, android 提供了一种 组件 service, 可以 作为单独的 进程 为 应用程序 提供服务. 

大家都知道 handler 是 用来完成 线程间的 通信, 但其实 Handler 提供了 进程间 通信的支持. 

一. 先举个 例子:

一.   service 端代码为:  

      在处理 客户端 请求的时候我们 可以看出来 进程 交互的 非 基本数据都被 存储到了 Bundle 中, 因此 如果我们 想传一些 定义的 对象, 可以让这些 对象 实现 Parcelable接口, 以便 放到 Bundle 中 , 进行进程间 交互.

     第二点 可以注意的是:当 Service 进程 处理好 请求后, 会 封装好 要返回的数据, 调用 message 的 replyTo 这个 Messenger 对象的 send 方法 把 Service 进程端 封装的 Message 传给 客户端. ( 下面会解释 replyTo 是啥).


二.    客户端 代码又 如下:

1. 创建 ServiceConnection 对象:  通过 onServiceConnected 方法, 我们 创建了 可以向 Service 发 请求的 Messenger 对象 ,其 引用为 server.


2.  于是乎, 我们 可以 调用 server 向 前面提到的 Service 进程 发出请求, 我们 创建一个 Message 消息 把 命令字 赋值给 msg.what, 然后 就可以 调用 server.send() 方法 把 这个 Message 发给 Service 进程处理, 但 如果 Service 进程想 通知 客户端一些 消息 应该怎么处理呢, 所以 我们 传给 Service 进程的消息 要 带上 replyTo 这个值, replyTo 是一个 处理 Service 进程数据返回的 Messenger.


3. 创建 用于 处理 service 进程返回 数据的 Messenger,说白了就是 创建 一个 可以暴漏给 Service 进程 调用的 远程 binder 对象,



二. 再讲一下原理:


    概述: 

            在 Service 端 创建 一个 Messenger 对象, 构造函数的入参为 Handler, 则 在 当前进程 中 创建一个 IMessenger.Stub 对应的 子类 MessengerImpl 的 Binder 对象, 这个 Binder 为 本地Binder. 在 Service 中的 onBinder() 回调方法中 调用 Messenger 对象的 getBinder() 进行返回( 实际上调用的是 MessengerImpl.asBinder() 方法), 

            在 Client 端中的 ServiceConnection 接口的实现类 中的 onServiceConnected() 方法的第二个参数 为 Service 返回的 代理 Binder, 则 使用 Messenger 构造函数 中 入参为 IBinder 的 创建一个 Messenger 对象,  在 Client 端 创建的 这个 Messenger 是 用来 向  Service 端 发送 Messager 消息的, Messager 消息 对应的 处理 逻辑 是在 Service 端 的 Messenger 对象中的 handleMessage(){} 方法中实现的.

            在前面只讲到了 从 Client 端发送 Message 消息 给 Service 端, 但如果 想 通过 Service 端返回 消息 给 Client 端呢, 则 在 Client 端 创建一个 构造函数入参 为 Handler 的 Messenger 对象 delReturn , 然后 将 Client端发给 Service 端 对应的 Message 的  replyTo 字段 赋值为 delReturn 指向的对象, 则 Service 端就可以 通过 Message.replyTo 对应的 Messenger 向 Client端发送 Message.


            小结一下 :  通过 Messenger 来 实现 进程间通信的 好处是:

                        1. 不用烦恼 前后台 约定的 进程间通信协议的变换(aidl文件) ,  因为 Messenger 机制里 可以通过 修改 handleMessage() 的实现就可以了,不用修改 远程调用 接口

                        2.  避免客户端调用 Service 远程 方法 的线程会被阻塞.  , Binder机制中 Client端 调用 Service 端 时, Client端对应的线程会等到 Service 端 线程返回才开始继续执行,, 由于 Messenger 在 ipc 通信上 借鉴了 Handler 机制,因此 可以把 方法执行 和方法返回分开 , Messenger 机制下的 client 端 对应的线程 无需 等待 消息 执行完成.


-------------------------------------------------------------------------------------------------------------------------------------------------

        1.  首先, 我们看到 IMessenger 对应的 aidl 文件: 可以知道 IMessenger 对应的是 一个 有 send(Message msg) 方法的Binder 对象.


        2. 在 Handler.MessengerImpl  类 中 我们可以看到 IMessenger.Stub 本地 binder 端 的代码实现为 : 通过 Handler 的 sendMessage() 方法把 获取到的Message 消息 发给对应的线程的looper中.


        3. 在 上面代码截图中, 我们可以看到 Handler 中 有一个 方法 getIMessenger(), 其作用是 返回一个 MessengerImpl() 对象实例. 在使用的时候 我们会 创建 Messenger 对象, 则 从 Messenger 的构造函数中 我们可以看到:


        --> Messenger 有 两个构造函数, 其中 一个 入参 为 Handler对象, 则 mTarget 对应的 是 IMessenger  aidl 接口 对应的 实体类.


        -->  下面是 入参 为 IBinder 对象, 则 target 为 IMessenger aidl 接口 对应的 代理类, 用来 把 消息 Messenger 从当前 进程 发到 IMessenger 对应的 实体类 所在的进程 进行处理:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容