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

来源:互联网 发布:plc圆弧插补算法实例 编辑:程序博客网 时间:2024/05/15 23:52

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;@Overridepublic 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);}@Overridepublic 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();}}@Overridepublic 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;@Overrideprotected 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() {@Overridepublic 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();}}@Overrideprotected 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() {@Overridepublic void onServiceConnected(ComponentName name, IBinder binder) {Log.d(this.getClass().getName(), "onServiceConnected");sender = new Messenger(binder);}@Overridepublic 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


1 0