1 Messenger 简介

​ Messenger 类实现了 Parcelable 接口,用于进程间传输并处理消息,调用流程如下:

  • Client 通过 bindService() 请求绑定 Service
  • Service 通过 messenger_s.getBinder() 获取 IBunder 并返回 Client
  • Client 通过 messenger_s =new Messenger(service) 获取 Service 的 Messenger
  • Client 通过 msg_c2s.replyTo=messenger_c 将自己的 Messenger 绑定到 msg_c2s
  • Client 通过 messenger_s.send(msg_c2s) 给 Service 发送消息
  • Service 通过 messenger_c=msg_c2s.replyTo 获取 Client 的 Messenger
  • Service 通过 messenger_c.send(msg_s2c) 给 Client 发送消息

​ 本文全部代码见→使用Messenger实现进程间通讯

2 项目结构

3 服务端 msger_S 代码

(1)创建服务

​ MyService.java

package com.example.msger_s;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log; public class MyService extends Service {
Messenger messenger_c; //客户端的Messenger @Override
public IBinder onBind(Intent intent) {
return messenger_s.getBinder();
} private Messenger messenger_s = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg_c2s) {
super.handleMessage(msg_c2s);
receive(msg_c2s);
messenger_c = msg_c2s.replyTo; //获取客户端的Messenger
send();
}
}); private void receive(Message msg) { //接收来自客户端的消息
Bundle bundle = (Bundle) msg.obj;
String msg_c2s = bundle.getString("msg_c2s");
Log.e("MyService", "来自客户端的消息:" + msg_c2s);
} private void send() { //给客户端返回消息
Message msg = new Message();
Bundle bundle1 = new Bundle();
bundle1.putString("msg_s2c", "hello client");
msg.obj = bundle1;
try {
messenger_c.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}

(2)注册服务

​ 在 AndroidManifest.xml 文件中 application 节点下注册 service,如下。

<service
android:name=".MyService"
android:exported="true">
<intent-filter>
<action android:name="com.xxx.msger_s"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>

(3)主 Activity

​ MainActivity.java

package com.example.msger_s;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

4 客户端 msger_C 代码

(1)设计布局

​ activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.msger_c.MainActivity"> <EditText
android:id="@+id/et_send"
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="hello service"
android:textSize="30dp"
android:background="#ffcc66"/> <Button
android:id="@+id/btn_send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:textSize="30sp"
android:text="发送"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="返回的消息:"
android:textSize="30sp"
android:layout_marginTop="100dp"/> <TextView
android:id="@+id/tv_receive"
android:layout_width="match_parent"
android:layout_height="80dp"
android:textSize="30sp"
android:background="#ffcc66"
android:layout_marginTop="20dp"/>
</LinearLayout>

​ 界面如下:

(2)主 Activity

​ MainActivity.java

package com.example.msger_c;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends AppCompatActivity {
private Messenger messenger_s; //服务端的Messenger
private EditText et_send;
private Button btn_send;
private TextView tv_receive; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
} private void init() {
et_send = (EditText) findViewById(R.id.et_send);
btn_send = (Button) findViewById(R.id.btn_send);
tv_receive = (TextView) findViewById(R.id.tv_receive);
btn_send.setOnClickListener(cl);
} View.OnClickListener cl = new View.OnClickListener(){
@Override
public void onClick(View v) {
hideInputMethod(MainActivity.this, v); //关闭输入法
if (v.getId()==R.id.btn_send) {
String msg_c2s = et_send.getText().toString();
sendMsg(msg_c2s);
}
}
}; private void sendMsg(String msg_c2s){
if (messenger_s==null) {
attemptToBindService();
}
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putString("msg_c2s",msg_c2s);
msg.obj = bundle;
msg.replyTo = messenger_c; //将客户端的Messenger传给服务端
try {
messenger_s.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
} private Messenger messenger_c = new Messenger(new Handler() { //客户端的Messenger
@Override
public void handleMessage(Message msg) { //处理服务端返回的消息
super.handleMessage(msg);
Bundle bundle = (Bundle) msg.obj;
String msg_s2c = bundle.getString("msg_s2c");
tv_receive.setText(msg_s2c);
}
}); private void attemptToBindService() {
Intent intent = new Intent();
intent.setAction("com.xxx.msger_s");
intent.setPackage("com.example.msger_s");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
} ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
messenger_s = new Messenger(service); //获取服务端的Messenger
} @Override
public void onServiceDisconnected(ComponentName name) {
messenger_s = null;
}
}; private void hideInputMethod(Activity act, View v) { //关闭输入法
InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(),0);
} @Override
protected void onStart() {
super.onStart();
if (messenger_s==null) {
attemptToBindService();
}
} @Override
protected void onStop() {
super.onStop();
if (messenger_s!=null) {
unbindService(conn);
}
}
}

5 效果展示

​ 点击【发送】按钮,在服务端可以收到发送的消息,如下:

​ 在客户端收到回复如下:

​ 声明:本文转自【Android】使用Messenger实现进程间通讯

【Android】使用Messenger实现进程间通讯的更多相关文章

  1. Android进程间通讯之messenger

    这两天在看binder,无意间在文档看到messenger这么个东西,感觉这个东西还挺有意思的,给大家分享一下. 平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都 ...

  2. Android进阶笔记04:Android进程间通讯(IPC)之Messenger

    一. Android进程间通讯之Messenger 的引入 (1)引言:      平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进程间通讯.它是基于消 ...

  3. Android查缺补漏(IPC篇)-- Bundle、文件共享、ContentProvider、Messenger四种进程间通讯介绍

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8387752.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...

  4. android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...

  5. Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8479282.html 在Android中进程间通信是比较难的一部分,同时又非常 ...

  6. Android查缺补漏(IPC篇)-- 进程间通讯之Socket简介及示例

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8425736.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...

  7. Android查缺补漏(IPC篇)-- 进程间通讯之AIDL详解

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...

  8. Android-Android进程间通讯之messenger

    转自‘https://www.cnblogs.com/makaruila/p/4869912.html 平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进 ...

  9. Android进程间通讯

    最近研究了一下Android进程间通讯,原来只是会用,但是只是会用是不行滴,就来研究一下. 刚开始看的时候,我的头是这么大,看了一夜的时候,头就变成这样了,,吓得宝宝赶紧上床休息了,. 先喝喝茶讲个故 ...

  10. Android AIDL 进行进程间通讯(IPC)

    编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3. ...

随机推荐

  1. 强大的PDF格式转换器--迅捷PDF转换器

    1.功能十分强大,具体如图所示,实现了多种文件格式的转换,PDF合并和PDF密码解除也帮了我很大的忙(注意这里的密码解除是强行解除,不需要你知道密码) 2.资源分享 https://www.aliyu ...

  2. CSS 动画 : 3D翻页动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. [转帖]AL32UTF8/UTF8(Unicode)数据库字符集含义 (文档 ID 1946289.1)

    AL32UTF8/UTF8(Unicode)数据库字符集含义 (文档 ID 1946289.1) 适用于: Oracle Database Cloud Schema Service - 版本 N/A ...

  4. [转帖]TLS1.3 正式版发布 — 特性与开启方式科普

    https://cloud.tencent.com/developer/article/1376033 互联网工程指导委员会(IETF)释出了传输层安全性协议的最新版本 TLS 1.3.TLS 被广泛 ...

  5. [转帖]SQL Server高级进阶之索引碎片维护

    https://www.cnblogs.com/atomy/p/15268589.html 一.产生原因及影响 索引是数据库引擎中针对表(有时候也针对视图)建立的特别数据结构,用来帮助查找和整理数据, ...

  6. [转帖]Kafka中Topic级别配置

    https://www.cnblogs.com/moonandstar08/p/6139502.html 一.Kafka中topic级别配置 1.Topic级别配置 配置topic级别参数时,相同(参 ...

  7. [转帖]PostgreSQL 10.0 preview 功能增强 - 国际化功能增强,支持ICU(International Components for Unicode)

    https://developer.aliyun.com/article/72935 标签 PostgreSQL , 10.0 , International Components for Unico ...

  8. [转帖]煮饺子与 docker、kubernetes 之间的关系

      前言:云原生的概念最近非常火爆,企业落地云原生的愿望也越发强烈.看过很多关于云原生的文章,要么云山雾罩,要么曲高和寡. 所以笔者就有了写<大话云原生>系列文章的想法,期望用最通俗.简单 ...

  9. [转帖]PCIe信息查询

    https://www.jianshu.com/p/b3a57fcaff8d 查询PCIe设备厂商信息 通过PCIe设备的描述信息进行查询 PCIe设备的描述:Class号.厂商号(vender id ...

  10. ccs3动画-div向上移动的动画

    <head> <meta charset="UTF-8"> <meta name="viewport" content=" ...