在上一篇里说了怎么启动一个service,start service就不多说了,比较简单,这里主要说一下bind service。如果只是AP内部的一个service,和AP在同一个process里面,在code里可以直接import到自定义的binder,那么像上次demo里说到的方式是可行的,但是如果是一个外部的service,又没有办法import到相应的binder class,那么就没法调到想要的API 了,这样该怎么处理呢?如果是在接受service顺序处理request,一次处理一个,那么比较好的实现方式应该是用messenger来辅助消息传输。
首先看一下service的code,要收消息,Handler肯定是少不了的了。但是要让对方也能把消息传过来,那就要在bind的时候把Messenger的binder return出去了。
//Service
private Messenger mMessenger = new Messenger(new MessengeHandler());
private class MessengeHandler extends Handler {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.d(TAG, "handleMessage what : " + msg.what);
switch(msg.what) {
case 0:
try {
Message m = new Message();
m.what = 100;
msg.replyTo.send(m);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mMessenger.getBinder();
}
当然client端就要在bind到service后把自己的Messenger发送给service 端,这样以来,两边就都有对方的Messenger了,就可以发消息到对方的queue里,通过不同的消息就可以映射不同的方法来执行,这样即使是在不同的process里也可以发送消息,并且不同担心API 引用不到的问题了。
//Client
Messenger mMessengerService = null;
Messenger mReplyMessenger = new Messenger(new MessengeHandler());
private class MessengeHandler extends Handler {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch(msg.what) {
case 100:
Log.d(TAG, " msg from service : " + msg.what);
break;
default:
super.handleMessage(msg);
break;
}
}
}
private ServiceConnection mMsgConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
try {
mMessengerService = new Messenger(service);
Message m = new Message();
m.what = 0;
m.replyTo = mReplyMessenger;
mMessengerService.send(m);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
private void bindMsgService() {
Intent service = new Intent(this, MyMessengerService.class);
this.bindService(service, mMsgConnection, Service.BIND_AUTO_CREATE);
}
private void unbindMsgService() {
if(mMsgConnection != null)
this.unbindService(mMsgConnection);
}
上面的这种方式一个缺陷就是对消息的处理不是并发的,只能对收到的message一个一个的处理,如果有并发处理的需求怎么办呢? 且听下回分解。