Android Service进程间双向通信之Messenger(系列4)

简介: Android Service进程间双向通信之Messenger(系列4)附录文章2虽然利用Service的Binder、bindService这些机制实现了Android Service与其他组件的相互通信,但实现手段并不唯一,Android体系架构中还有一个解决方案:利用Android Messenger实现Service进程间双向通信。

Android Service进程间双向通信之Messenger(系列4)

附录文章2虽然利用Service的Binder、bindService这些机制实现了Android Service与其他组件的相互通信,但实现手段并不唯一,Android体系架构中还有一个解决方案:利用Android Messenger实现Service进程间双向通信。


先丢出代码。


先写一个MyService.java,继承自Service:

package zhangphil.service;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;

public class MyService extends Service {

	private Messenger messenger;

	@Override
	public void onCreate() {
		Log.d(this.getClass().getName(), "onCreate");

		Handler handler = new Handler() {
			public void handleMessage(Message msg) {
				Log.d(this.getClass().getName(), msg.what + ":" + msg.obj);

				// 收到来自于Activity的消息后立即响应回复一条消息。
				sendMessageToActivity(msg.replyTo);
			}
		};

		messenger = new Messenger(handler);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}

	private void sendMessageToActivity(Messenger mMessenger) {
		Message msg = Message.obtain();
		msg.what = 0x09;
		msg.obj = "hello,i'm from Service !";

		try {
			mMessenger.send(msg);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return messenger.getBinder();
	}

	// @Override
	// public boolean onUnbind(Intent intent) {
	// Log.d(this.getClass().getName(), "onUnbind");
	// return super.onUnbind(intent);
	// }
	//
	// @Override
	// public void onDestroy() {
	// Log.d(this.getClass().getName(), "onDestroy");
	// }
}



测试的Activity MainActivity.java:

package zhangphil.service;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
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.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

	private ServiceConnection sc = null;
	private Messenger sender, receiver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		bindMyService();

		Handler handler = new Handler() {
			public void handleMessage(Message msg) {
				Log.d(this.getClass().getName(), msg.what + ":" + msg.obj);
			}
		};

		receiver = new Messenger(handler);

		Button sendToService = (Button) findViewById(R.id.sendToService);
		sendToService.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				sendMessageToService(sender);
			}
		});
	}

	private void sendMessageToService(Messenger messenger) {
		Message msg = Message.obtain();
		msg.what = 0x08;
		msg.obj = "hello,i'm from Activity !";

		// 设置一个Messenger receiver,receiver是提供给Service使用来给Activity响应的目标。
		msg.replyTo = receiver;

		try {
			messenger.send(msg);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindMyService();
		Log.d(this.getClass().getName(), "onDestroy");
	}

	// private void startMyAppService() {
	// Intent intent = new Intent(this, MyService.class);
	// this.startService(intent);
	// }

	private void bindMyService() {
		sc = new ServiceConnection() {

			@Override
			public void onServiceConnected(ComponentName name, IBinder binder) {
				Log.d(this.getClass().getName(), "onServiceConnected");

				sender = new Messenger(binder);
			}

			@Override
			public void onServiceDisconnected(ComponentName name) {
				Log.d(this.getClass().getName(), "onServiceDisconnected");
			}
		};

		Intent intent = new Intent(this, MyService.class);
		this.bindService(intent, sc, Service.BIND_AUTO_CREATE);
	}

	// private void stopMyService() {
	// Intent intent = new Intent(this, MyService.class);
	// boolean bool = this.stopService(intent);
	// }

	private void unbindMyService() {
		if (sc != null)
			this.unbindService(sc);
	}
}

以下是代码说明。
先说一下代码要实现的简单目的:首先绑定后台Service:MyService,然后Activity向后台Service发送一条的简单字符串消息;当后台的Service收到消息后,立即响应再发给前台的Activity一个字符串消息。
使用Android Messenger实现Service与其他组件之间的双向通信需要注意几点内容:
(A)和参考文章2中的Service不同的是,这一次,public IBinder onBind(Intent intent)返回的是不是自己写的Binder,而是一个从Messenger获得的Binder。构造Messenger时候给其传递一个handler,handler用于接受发送给Service的消息Message(在本例中是Activity发给Service的消息)。
(B)在本例中,后台Service与前台Activity通信‘由后向前’的通信关键是:在Activity给Service发送消息时候,设置一个replyTo的Messenger,此replyTo字段中的Messenger将被消息接受者(Service)捕获提取,然后作为目标靶Messenger发消息,从而实现Service接受消息后,可以用replyTo字段中的Messenger返还一个消息给Activity。
(C)和参考文章2类似,前台的Activity要绑定Service,ServiceConnection绑定后在onServiceConnected中获得一个可以给后台Service发消息的Messenger(在本例中是Activity中的sender)。此Messenger即是和Activity和Service通信的桥梁。
(D)前台Activity如果要打算接受来自于后台Service的消息,那么就必须再创建一个额外的Messenger(在本例中是Activity中的receiver),同样需要创建一个Activity自己的Handler,handler传递给receiver,Activity的Handler将接收来自于Service发送过来的消息。
(E)若要实现双向通信,务必记住,前台Activity用(C)阶段获得的Messenger sender给后台的Service发送消息时候,务必将Activity中的Messenger receiver赋值到Message的replyTo,传递给后台的Service。即msg. msg.replyTo = receiver


附录参考文章:
文章1:《Android Service简介(系列1)》链接地址:http://blog.csdn.net/zhangphil/article/details/49373939
文章2:《Android Activity与Service数据交互:Binder、bindService(系列2)》链接地址:http://blog.csdn.net/zhangphil/article/details/49385005
文章3:《Android Service之串行化Service:IntentService(系列3)》链接地址:http://blog.csdn.net/zhangphil/article/details/49387139

文章4:《Android进程间通信(IPC)的AIDL机制:Hello World示例 》链接地址:http://blog.csdn.net/zhangphil/article/details/43876657


相关文章
|
2月前
|
存储 Unix Linux
进程间通信方式-----管道通信
【10月更文挑战第29天】管道通信是一种重要的进程间通信机制,它为进程间的数据传输和同步提供了一种简单有效的方法。通过合理地使用管道通信,可以实现不同进程之间的协作,提高系统的整体性能和效率。
|
2月前
|
消息中间件 存储 供应链
进程间通信方式-----消息队列通信
【10月更文挑战第29天】消息队列通信是一种强大而灵活的进程间通信机制,它通过异步通信、解耦和缓冲等特性,为分布式系统和多进程应用提供了高效的通信方式。在实际应用中,需要根据具体的需求和场景,合理地选择和使用消息队列,以充分发挥其优势,同时注意其可能带来的复杂性和性能开销等问题。
|
3月前
|
存储 Python
Python中的多进程通信实践指南
Python中的多进程通信实践指南
40 0
|
4月前
|
存储 监控
【Azure Cloud Service】在Azure云服务中收集CPU监控指标和IIS进程的DUMP方法
在使用Cloud Service服务时,发现服务的CPU占用很高,在业务请求并不大的情况下,需要直到到底是什么进程占用了大量的CPU资源,已经如何获取IIS进程(w3wp.exe)的DUMP文件?
|
4月前
|
Java Android开发 数据安全/隐私保护
Android中多进程通信有几种方式?需要注意哪些问题?
本文介绍了Android中的多进程通信(IPC),探讨了IPC的重要性及其实现方式,如Intent、Binder、AIDL等,并通过一个使用Binder机制的示例详细说明了其实现过程。
442 4
|
5月前
|
Linux
Linux源码阅读笔记13-进程通信组件中
Linux源码阅读笔记13-进程通信组件中
|
5月前
|
消息中间件 安全 Java
Linux源码阅读笔记13-进程通信组件上
Linux源码阅读笔记13-进程通信组件上
|
5月前
|
消息中间件 存储 安全
python多进程并发编程之互斥锁与进程间的通信
python多进程并发编程之互斥锁与进程间的通信
|
5月前
|
微服务 Windows
【Azure微服务 Service Fabric 】在SF节点中开启Performance Monitor及设置抓取进程的方式
【Azure微服务 Service Fabric 】在SF节点中开启Performance Monitor及设置抓取进程的方式
|
5月前
|
Python
Python IPC深度探索:解锁跨进程通信的无限可能,以管道与队列为翼,让你的应用跨越边界,无缝协作,震撼登场
【8月更文挑战第3天】Python IPC大揭秘:解锁进程间通信新姿势,让你的应用无界连接
31 0

热门文章

最新文章

相关实验场景

更多