基于Message的进程间通信实例
来源:互联网 发布:mac翻墙用什么软件好 编辑:程序博客网 时间:2024/05/16 17:58
一. 概述
前面已经讨论过基于message的线程间通信,通过Handler类来处理,实际上,跨进程的Messasge通信也是可以的。在Handler类中,有如下定义:
final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl(); return mMessenger; } } private final class MessengerImpl extends IMessenger.Stub { public void send(Message msg) { Handler.this.sendMessage(msg); } }
这里我们关注的是IMessenger接口,它的定义如下:
package android.os;import android.os.Message;/** @hide */oneway interface IMessenger { void send(in Message msg);}
可以看到,定义了一个发送消息的接口。从MessengerImpl的实现来看,实现发送消息是通过与之关联的Handler来发送的。一个Messenger会关联一个Handler对象。进程间消息通信的本质是:
1. Messenger类实现了Parcelable接口,它可以通过Binder通信从一个进程发送到另一个进程。
2. 一方面,Messenger类通过构造函数,传入了一个Handler对象,通过Handler类提供的getIMessenger()方法,持有了与关联的Handler对象的sendMessenge方法的通路,即通过Messenger的send方法发送消息时,实际上会调用与之关联的Handler对象的sendMessage方法。
3. 另一方面,为了建立与另一方的通信,需要借助如下构建函数打通与另一方的通信线路
public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); }
这样就建立一个Binder通信线路。
4. 通过这条Binder通信线程,即借助上述所说的构造函数创建的Messenger对象,将Message发送到Binder通信的另一方。这个Messenger对象所关联的Handler对象其实是在另一个进程中。所以,它通过该对象调用send方法,实质上就是调用与之关联的Handler对象的sendMessage方法,从面可以在对应的handleMessage方法中处理发送过来的消息。这样就实现了一方通信,即从本进程向另一个进程中发送了一个Message。
5. 接下来,另一个进程处理收到的Message,进行解析,做些处理后,又通过Message对象携带的Messagener对象(Message.replyTo),向本进程发送回一个Message消息,至此,完成了一次双向通信。
使用如下图示说明如下:
二、实例分析
如上所述,要实现基于Message的进程间通信,至少要创建三个Messenger对象,其中两个Messenger对象会传入Handler对象,另一个Messenger对象则用于建立Binder通信线路,会传入一个IBinder对象。
如下 所示,我们创建了MessengerService类,它将作为通信的一方:
public class MessengerService extends Service {private final Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {Message reply = Message.obtain();reply.copyFrom(msg);try {System.out.println("receive handler call from remote...");System.out.println("ARG1: " + msg.arg1);System.out.println("ARG2: " + msg.arg2);msg.replyTo.send(reply);} catch (RemoteException e) {}}};private final Messenger mMessenger = new Messenger(mHandler);public MessengerService() {}@Overridepublic IBinder onBind(Intent intent) {return mMessenger.getBinder();}}
特别留意的是它重载了onBind方法,通过此方法,服务的调用者就建立了与本地mMessgenger通信的一条线程。
在通信的另一方,我们的定义如下:
public class MessengerTest extends Activity {private Messenger mServiceMessenger;private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName name, IBinder service) {synchronized (MessengerTest.this) {mServiceMessenger = new Messenger(service);// MessengerTest.this.notifyAll();}}public void onServiceDisconnected(ComponentName name) {mServiceMessenger = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.hello);Button btn = (Button) findViewById(R.id.btn);btn.setOnClickListener(new OnClickListener() {public void onClick(View v) {// TODO Auto-generated method stub(new TestThread()).doTest(1000);}});}@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();this.unbindService(mConnection);}@Overrideprotected void onStart() {// TODO Auto-generated method stubsuper.onStart();this.bindService(new Intent(MessengerTest.this, MessengerService.class),mConnection, Context.BIND_AUTO_CREATE);}private class TestThread extends TestHandlerThread {private Handler mTestHandler;private Messenger mTestMessenger;public void go() {synchronized (MessengerTest.this) {mTestHandler = new Handler() {public void handleMessage(Message msg) {TestThread.this.handleMessage(msg);}};mTestMessenger = new Messenger(mTestHandler);TestThread.this.executeTest();}}public void executeTest() {Message msg = Message.obtain();msg.arg1 = 100;msg.arg2 = 1000;msg.replyTo = mTestMessenger;try {mServiceMessenger.send(msg);} catch (RemoteException e) {}}public void handleMessage(Message msg) {if (msg.arg1 != 100) {failure(new RuntimeException("Message.arg1 is not 100: "+ msg.arg1));return;}if (msg.arg2 != 1000) {failure(new RuntimeException("Message.arg2 is not 1000: "+ msg.arg2));return;}if (!mTestMessenger.equals(msg.replyTo)) {failure(new RuntimeException("Message.replyTo is not me: "+ msg.replyTo));return;}success();}};}
我们在创建mConnectioin对象时,在onServiceconnected方法里,创建了mServiceMessenger,它将作为信使,将本进程发送的消息传递给另一方。
本地创建的Messenger对象是mTestMessager.
测试程序如下的代码如下所示:
abstract class TestHandlerThread {private boolean mDone = false;private boolean mSuccess = false;private RuntimeException mFailure = null;private Looper mLooper;public abstract void go();public TestHandlerThread() {}public void doTest(long timeout) {(new LooperThread()).start();synchronized (this) {long now = System.currentTimeMillis();long endTime = now + timeout;while (!mDone && now < endTime) {try {wait(endTime - now);} catch (InterruptedException e) {}now = System.currentTimeMillis();}}mLooper.quit();if (!mDone) {throw new RuntimeException("test timed out");}if (!mSuccess) {throw mFailure;}}public Looper getLooper() {return mLooper;}public void success() {synchronized (this) {mSuccess = true;quit();}}public void failure(RuntimeException failure) {synchronized (this) {mSuccess = false;mFailure = failure;quit();}}class LooperThread extends Thread {public void run() {Looper.prepare();mLooper = Looper.myLooper();go();Looper.loop();synchronized (TestHandlerThread.this) {mDone = true;if (!mSuccess && mFailure == null) {mFailure = new RuntimeException("no failure exception set");}TestHandlerThread.this.notifyAll();}}}private void quit() {synchronized (this) {mDone = true;notifyAll();}}}
为了演示跨进程通信,我们将service在另一个进程中启动:
在AndroidManifest.txml中加入如下声明:
<service android:name=".messagetest.MessengerService" android:process=":remote" > <intent-filter> <action android:name="com.fyj.demo.messagetest.MessengerService" /> </intent-filter> </service>
完。
- 基于Message的进程间通信实例
- Android--基于Message的进程间通信
- Android 基于Message的进程间通信
- 基于Message的线程间通信实例
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析
- Android 基于Message的进程间通信 Messenger完全解析【转】
- 安卓-基于Message的进程间通信 Messenger完全解析
- Android的进程间通信/AIDL/Message等机制
- Linux:进程通信之消息队列Message实例
- 第一章总结
- 选择排序
- Xcode6编译SDWebImage报错解决方法(SDWebImageDownloaderOperation.m错误)
- Python 爬虫批量下载美剧 from 人人影视 HR-HDTV
- 问题及代码
- 基于Message的进程间通信实例
- IQueryFilter.whereclause的SQL语句设置规则
- 常用排序算法之性能比较
- 如何通过sql准确查出一天的数据
- 命令行关闭开启和删除驱动服务
- 信息安全属性CIA
- Android View坐标getLeft, getRight, getTop, getBottom
- POJ 3842 An Industrial Spy 快筛质数+STL乱搞
- Android File Transfer – 在 Mac 上也能读取 Android 设备文件