如果想要進行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版本的 新版的源碼沒去研究,這部分應該是一致的。下面是個簡單的草圖,算是個總結。