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. 【SHELL】反斜杠解决多个shell实例扩展

    本意是想获取代码仓相对路径,代码如下 base_dir=`pwd` repo forall -c '{     user_dir=$(realpath --relative-to="$bas ...

  2. idea 修改 jsp文件之后不生效问题

  3. JMS微服务开发示例(七)使用 Serilog 作为日志提供者

    nuget 引入: Serilog.Extensions.LoggingSerilog.Settings.ConfigurationSerilog.Sinks.ConsoleSerilog.Sinks ...

  4. Oracle19c 多字符集支持的PDB

    Oracle19c 多字符集支持的PDB 背景 想在一个数据库里面支持多种字符集 突然发现Oracle12c开始已经可以实现一个CDB下面可以有多个不同字符集的PDB了 所以想着今天验证一下. 环境信 ...

  5. [转帖]资料整理——Oracle版本历史(很全面)(Releases and versions of Oracle Database)

    资料来源: https://en.wikipedia.org/wiki/Oracle_Database Oracle Database Version Initial Release Version ...

  6. [转帖]是什么让 Redis“气急败坏”回击:13 年来,总有人想替 Redis 换套新架构

    https://www.infoq.cn/article/AlF5NIhHdskayl0MTyQG 回击就代表输了?! 今年年中,一位前谷歌.前亚马逊的工程师推出了他创作的开源内存数据缓存系统 Dra ...

  7. 基于OpenJDK部署clickhouse-local镜像的快捷方法

    基于OpenJDK部署clickhouse-local镜像的快捷方法 摘要 前期搭建了一套基于OpenJDK的Clickhouse的服务端的镜像 可以简单使用dbeaver进行连接与使用. 后来发现需 ...

  8. [转帖]TiDB 5.1 Write Stalls 应急文档

    https://tidb.net/blog/ac7174dd#4.%E5%88%A4%E6%96%AD%E6%98%AF%E5%90%A6%E5%87%BA%E7%8E%B0%E4%BA%86%20w ...

  9. [转帖]Python基础之判断和循环(三)

    https://www.jianshu.com/p/5a7552821c63 一.判断 关于判断,跟字面意思一样,就是判断某一个时刻应不应该做某件事: 语法: if 判断条件: 执行语句-- else ...

  10. [转帖]shell删除文件前几行或后几行

    https://www.cnblogs.com/1394htw/p/14852207.html shell删除文件前几行或后几行 #!/bin/bash #删除前两行 sed -i '1,2d' fi ...