如果想要进行IPC通信,一般写一个AIDL接口,再写一个Service子类,然后实现AIDL接口 当做IBinder返回给Activity界面层。
如果不想写AIDL接口文件,只是单I线程中与Service进行通信 我们可以用Android写好的Messenger类来处理,一样能将消息传递给Service进行通信。
先写上基本代码:
public class MyService extends Service {
Messenger messenger = null;
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
messenger = new Messenger(handler);//实例化一个对象,并将Handler传入绑定,UI MQ消息检测
}
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
Log.d("","Msg:" + msg.what + ";" + msg.obj);
}
};
/* (non-Javadoc)
* @see android.app.Service#onBind(android.content.Intent)
*/
@Override
public IBinder onBind(Intent arg0) {
return messenger.getBinder();//返回Binder接口
}
}
MyActivity 中部分代码
<span style="white-space:pre"> </span>Messenger messenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService(new Intent(this,MyService.class), conn, Context.BIND_AUTO_CREATE);//一样绑定一个Connection
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName cn) {
}
@Override
public void onServiceConnected(ComponentName cn, IBinder ibiner) {
messenger = new Messenger(ibiner);//得到Service中的Messenger
Log.d("","OK messenger connected........");
}
};
public void sendMsg(int what, String msg){ //这个方法就是自己的业务信息发送消息 传递到Service中 有 Handler处理。
if (messenger == null) {
return;
}
Message msg1 = Message.obtain();
msg1.what = what;
msg1.obj = msg;
try {
messenger.send(msg1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
以上的代码非常简单。
下面看看Messenger源码其实是个包装类,它本身就是可以被IPC投递的对象,因为用了Parcelable接口。
public Messenger(Handler target) { //之前传递的Handler到这里,
mTarget = target.getIMessenger(); //得到的其实是Handler里面的IMessenger接口
}
public void send(Message message) throws RemoteException {
mTarget.send(message);//具体有IMessenger接口发送
}
public IBinder getBinder() {
return mTarget.asBinder();
}
//注释我都去掉了
再看看Handler源码是如何发消息的
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();//这个实现了IMessenger远程IPC接口,AIDL
return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub { //实现在这个地方
public void send(Message msg) {
Handler.this.sendMessage(msg);//本质上还是有 Handler来发送消息
}
}
可以看出IMessenger这个远程通信IPC接口 包含了send(Message msg)方法,其本质还是获取了我们MyService中的Handler对象进行发送消息。
IMessenger.aidl
内容如下
package android.os;
import android.os.Message;
/** @hide */
oneway interface IMessenger {
void send(in Message msg);
}
以上源码是4.1版本的 新版的源码没去研究,这部分应该是一致的。下面是个简单的草图,算是个总结。