Messenger类
Messenger类利用Binder实现进程间通信,
public final class Messenger implements Parcelable {
private final IMessenger mTarget;
/*
server端Messenger构造函数,输入为一个Handler,用来处理消息
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
/**
* Retrieve the IBinder that this Messenger is using to communicate with
* its associated Handler.
*
* @return Returns the IBinder backing this Messenger.
*/
//server端在onBind时调用,返回IMessenger
public IBinder getBinder() {
return mTarget.asBinder();
}
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
//构造MessengerImpl的client端IBinder
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
/**
* Send a Message to this Messenger's Handler.
*
* @param message The Message to send. Usually retrieved through
* {@link Message#obtain() Message.obtain()}.
*
* @throws RemoteException Throws DeadObjectException if the target
* Handler no longer exists.
*/
//send函数也是借助mTarget,即IMessenger发送数据
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
}
关于target.getIMessenger(),即Handler的getIMessenger(),
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
//MessengerImpl是IMessenger server端的对象
mMessenger = new MessengerImpl();
return mMessenger;
}
}
//MessengerImpl是server,实现了IMessenger.aidl的接口
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
//server端将该meg交给handler处理
Handler.this.sendMessage(msg);
}
}
1. Messenger实现IPC的关键其实是借助了IMessenger mTarget
,client通过send()发送message,到server端调用的是MessengerImpl的send(),将msg交给Handler处理;
2. 一个Messenger和一个handler相关联,Messenger只是信使,把信送到handler,处理还是由handler处理。
简单例子
server端,
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;
/**
* Handler of incoming messages from clients.
* server端处理消息的handler
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
* Target we publish for clients to send messages to IncomingHandler.
* server端构造一个Messenger,和自定义的Handler相关联
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
* client可以调用bindService()绑定到一个service.
* Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder.
* 这里返回的是MessengerImpl对象
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
client端,
public class ActivityMessenger extends Activity {
/** Messenger for communicating with the service. */
Messenger mService = null;
/** Flag indicating whether we have called bind on the service. */
boolean mBound;
/**
* Class for interacting with the main interface of the service.
* client通过bindService()去连接service,
* 绑定是异步的.bindService()会立即返回,它不会返回IBinder给客户端.要接收IBinder,
* 客户端必须创建一个ServiceConnection的实例并传给bindService().ServiceConnection
* 包含一个回调方法,系统调用这个方法来传递要返回的IBinder.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
// 利用IMessenger创建Messenger
mService = new Messenger(service);
mBound = true;
//给server端发送数据
sayHello();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};
public void sayHello() {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
//调用send函数发送数据
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to the service
// client调用bindService()
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
上面的例子演示了client向server端发送数据,server接收,但是有时候server也想回应client,其实做法是类似的,如果想要server响应client,我们需要在client中创建一个handler并创建一个新的Messenger(server),并把这个Messenger对象通过Message的replyTo参数传递给server,服务端就可以通过这个replyTo参数就可以回应client了,这里略过。