IPC-Messenger使用实例
需求假设:现在2个不同的应用需要相互直接传递消息.这个时候使用AIDL 就是很好的选择.为了使这份笔记有更好的价值,这里客户端要求可以接到服务器的通知也就是说客户端让服务器做了一件事件,服务端做好了之后需要告诉客户端.也就是类似观察者模式.
注意:
Messenger的消息传递是串行的,也就是说服务端是按照顺序一个个来来处理.不适合有大量并发请求的.这个时候用使用AIDL就合适一些.
1.服务端进程
首先,我们需要在服务器创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messenger对象,然后再service的onBind()中返回这个Messenger对象底层的Binder.
2.客户端进程
首先要绑定到服务端的Service,连接成功后,使用服务端放回的IBinder对象来创建一个Messenger对象,通过这个Messenger对象就可以给服务端发送消息了.发送的消息为Message对象.如果需要服务器能否在处理完成客户端发送的消息之后给客户端一个回复,就需要在客户端在创建一个新的Messenger,并把这个Messenger通过消息对象Message的参数replyTo传递到服务端.服务器就可以通过这个replyTo参数来给客户端发送消息,从而到达回复客户端的要求.
3.代码实现
3.1服务端代码实现
AndroidManifest.xml
<service android:name="com.example.messenger.MessengerService"
android:process=":other2">
</service>
MessengerService.java
package com.example.messenger;
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 MessengerService extends Service {
private static final String TAG = "MessengerService";
private final int ADDBOOK = 1001;
private final int ADDBOOK_SUCCESSED = 1002;
private Messenger mMessenger = new Messenger(new MessengerHandler());
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case ADDBOOK:
Bundle bundle = msg.getData();
String name = bundle.getString("name");
Log.d(TAG,"add book name=" + name);
Messenger client = msg.replyTo;
Message relpyMessage = Message.obtain(null, ADDBOOK_SUCCESSED);
Bundle b = new Bundle();
b.putString("reply_msg", "已經接到你的要求并处理!");
relpyMessage.setData(b);
try {
client.send(relpyMessage);//给客户端回复消息
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
}
3.2客户端代码实现
package com.example.messenger;
import com.example.demo1.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.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MessengerActivity extends Activity implements OnClickListener{
private static final String TAG = "MessengerActivity";
private static final int ADDBOOK = 1001;
private static final int ADDBOOK_SUCCESSED = 1002;
private TextView tv;
private Messenger mGetReplyMessenger = new Messenger(new MessengerReplyHandler());
private Messenger mService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_binder);
Button send = (Button)findViewById(R.id.bt_send);
send.setOnClickListener(this);
tv = (TextView)findViewById(R.id.tv_msg_response);
bindService(new Intent(this, MessengerService.class), mConn, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
}
};
@Override
public void onClick(View v) {
Message m = Message.obtain(null, ADDBOOK);
Bundle b = new Bundle();
b.putString("name", "书名:Android xxx");
m.setData(b);
m.replyTo = mGetReplyMessenger;//给客户端设置一个用于给客户端回调的Messenger
try {
mService.send(m);
} catch (RemoteException e) {
e.printStackTrace();
}
}
class MessengerReplyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case ADDBOOK_SUCCESSED:
String response = msg.getData().getString("reply_msg");
Log.d(TAG, "response=" + response);
tv.setText(response);
break;
default:
super.handleMessage(msg);
break;
}
}
}
@Override
protected void onDestroy() {
unbindService(mConn);
super.onDestroy();
}
}