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】查找文件并删除

    find . -iname file-name |xargs -I % rm -rf %

  2. 【FreeRTOS】堆内存管理

    动态内存分配及其与FreeRTOS的相关性 为了使FreeRTOS更易用,内核对象(如任务.队列.信号量.事件组)不在编译期静态分配,而是在运行时动态分配,FreeRTOS在内核对象创建时分配RAM, ...

  3. idea报错 "cannot access ..."的解决办法

    File -> Invalidate Caches -> Invalidate and Restart

  4. makefile文件详解

    1. make 编译:将源代码文件翻译成处理器可执行的二进制文件的过程,这个过程的时间区间称为编译时 构建:指定多个编译过程的先后顺序 make命令是常用的构建工具,诞生于1977年,主要用于C/C+ ...

  5. JVM内存用量的再学习

    JVM内存用量的再学习 背景 最近解决一个SQLServer的问题耗时很久. 最终找到了一个看似合理的问题解释. 但是感觉不能只是总结于数据库方面 因为为了解决这个问题增加了很多监控措施. 所以想就这 ...

  6. [转帖]nginx 反向代理 URL替换方案

    nginx 提供反向代理服务,日常开发过程中有时候我们需要使用nginx 作为代理服务根据url的不同去访问不同的服务器或者不同端口,如下提供两种方案. 1.直接替换location  匹配部分 1. ...

  7. [转帖]Linux-计算毫秒数

    https://www.cnblogs.com/yeyuzhuanjia/p/15822653.html date +%s返回自划时代以来的秒数. date +%s%N返回秒数+当前纳秒数. 因此,e ...

  8. [转帖]VMware ESXi 各版本号对照表

    本博文转自以下链接: VMware ESXi Release and Build Number History | virten.net vSphere ESXi 7.0 Name Patch Dat ...

  9. CentOS7 RPM离线安装PG12的办法

    1. 先需要下载相应的rpm包 地址 https://pkgs.org/search/?q=postgresql12 一般至少要下载如下四个包 postgresql12-12.3-1PGDG.rhel ...

  10. 【解决了一个小问题】vm-agent中,如何对envoy这样的特殊expoter路径做处理?

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 envoy这个组件的expoter路径为 /stats/p ...