您的位置:首页 > 移动开发 > Android开发

Android进程间通信之--Messenger(信使)

2016-07-07 21:19 417 查看

Messenger

在古代,信息的传输不够发达,信件的传递都是通过信使(Messenger)来完成的,信使把信件(Message)从一个地方送到另一个地方,然后用把另外一个地方的信件带回来。架构师们从这种通讯方式中抽象出来了Android进程间的一种通信方式—Messenger

信件从C地送到S地:

地方C要想把信件送到地方S,在C地得有一个S地的信使S_M,我们把信件C_m交给信使S_M,信使S_M就把信件C_m送到了S地。

信件从S地送到C地:

地方S要想把信件送到地方C,在S地得有一个C地的信使C_M,他们把信件S_m交给信使C_M,信使C_M就把信件S_m送到了C地。

Android架构师的抽象:

C和S都是一个进程,只是运行在各自的空间里面;C_M和S_M都是信使,只是他们属于不同的地方信使;C_m和S_m都是信件,只是他们是不同的人写的而已;C地和S地的人收到了信件过后会去读,然后C、S进程分别有了自己的Handler去处理信件m,并且C和S进程可以使用相同的Handler去处理信件。

以上就是现实生活中抽象出来的一种通信模式–Messenger

接下来我们看一下代码的实现

我们先写一个S进程:

RemoteService.java

package com.fht.ada.messenger;

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

public class RemoteService extends Service {
private Messenger mMessenger =new Messenger(new MessengerHander());
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}


为了使这个服务运行在单独的进程中我们需要在AndroidManifest.xm文件中做如下配置

<service
android:name="com.fht.ada.messenger.RemoteService"
android:process=":remote.service" >
<intent-filter>
<action android:name="com.fht.ada.messenger.RemoteService" />
</intent-filter>
</service>


在这个进程中我们new了一个mMessenger信使,它用来传递客户端的信件Message,并且由new MessengerHander()来处理信件

接下来我看一下MessageHander是如何处理信件的

MessengerHander.java

package com.fht.ada.messenger;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class MessengerHander extends Handler {
private static final String TAG = "Messenger";

public void handleMessage(android.os.Message msg) {
Messenger messenger = msg.replyTo;
switch (msg.what) {
case 0:// 收到了客户端发过来的消息,然后回复客户端
Log.i(TAG, "################service####################");
Log.i(TAG, "client-->service : " + msg.getData().getString("msg"));
Message replyMesage = Message.obtain(null, 1);
Bundle data = new Bundle();
data.putString("msg", "我收到了你的消息,我会尽快处理你发送的消息 ");
replyMesage.setData(data);
try {
messenger.send(replyMesage);
} catch (RemoteException e) {
e.printStackTrace();
}
Log.i(TAG, "################service####################");
break;
case 1:// 处理客户端回复的消息
Log.i(TAG, "################client####################");
Log.i(TAG, "service-->client : " + msg.getData().getString("msg"));
Log.i(TAG, "################client####################");
break;
}
};

}


这里是处理信件的,并且客户端和服务器端是使用相同的处理代码

最后来看一下C进程的实现

ClientActivity.java

package com.fht.ada.messenger;

import com.fht.ada.R;

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.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;

public class ClientActivity extends Activity {
private static final String TAG = "Messenger";
Messenger mMessenger;
Messenger mReplyMessenger = new Messenger(new MessengerHander());

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_client_messenger);
Intent service = new Intent(this, RemoteService.class);
this.bindService(service, mConn, Context.BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
super.onDestroy();
this.unbindService(mConn);
}

ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mMessenger = null;
}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
}
};

public void sendMessage(View view) {
String strMsg = "我输入的信息";
Message msg = Message.obtain(null, 0);
Bundle data = new Bundle();
data.putString("msg", strMsg);
msg.setData(data);
msg.replyTo = mReplyMessenger;
try {
if (mMessenger != null) {
mMessenger.send(msg);
} else {
Log.i(TAG, "远程连接断开");
}
} catch (RemoteException e) {
Log.i(TAG, "远程连接出问题");
e.printStackTrace();
}
}
}


在客户端只需要调用sendMessage方法就可以向S进程发送一个Message,并且C进程会受到S进程的反馈Message。就这样就实现了进程间的通信了

源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: