上一篇講到用AIDL實現程式間通訊,地址:Android程式間通訊之AIDL
AIDL的底層是通過Binder進行通訊的,通過追蹤.aidl編譯後自動生成的檔案我們知道,檔案中的Stub類用於服務端,Proxy類用於客戶端呼叫,那麼可否直接通過繼承Binder類實現多程式通訊呢?下面就來試一試。
本文例子中的原始碼地址:程式間通訊之Binder
效果圖:
服務端程式碼,BinderService.java:
首先繼承Binder 類,實現onTransact()供客戶端呼叫,同樣通過onBind()返回Binder例項:
private static final java.lang.String DESCRIPTOR = "org.ninetripods.mq.multiprocess_sever.IAidlCallBack";
private static final int KEY_FLAG = 0x110;
private class MyBinder extends Binder {
/**
* @param code 唯一標識,客戶端傳遞標識執行服務端程式碼
* @param data 客戶端傳遞過來的引數
* @param reply 伺服器返回回去的值
* @param flags 是否有返回值 0:有 1:沒有
* @return
* @throws RemoteException 異常
*/
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
switch (code) {
case KEY_FLAG:
//標識伺服器名稱
data.enforceInterface(DESCRIPTOR);
Apple apple = new Apple("紅星蘋果", 15f, getString(R.string.response_binder_info));
reply.writeNoException();
reply.writeInt(1);
apple.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
return true;
}
return super.onTransact(code, data, reply, flags);
}
}
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
複製程式碼
在AndroidManifest.xml中宣告一下:
<service
android:name=".BinderService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.mq.binder.service" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
複製程式碼
客戶端程式碼:BinderActivity.java:
首先編寫ServiceConnection 類來獲得Binder例項,來傳送和接收資料:
private ServiceConnection binderConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
isBound = true;
mService = service;
if (mService != null) {
//宣告兩個Parcel型別資料(_data和_reply) 一個用於傳輸資料 一個用於接收資料
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
Apple apple;
try {
//與伺服器端的enforceInterface(DESCRIPTOR)對應
_data.writeInterfaceToken(DESCRIPTOR);
//呼叫服務端的transact()傳輸資料
mService.transact(KEY_FLAG, _data, _reply, 0);
_reply.readException();
if (0 != _reply.readInt()) {
//接收服務端響應資料
apple = Apple.CREATOR.createFromParcel(_reply);
} else {
apple = null;
}
showMessage(apple != null ? ("\n" + apple.getNoticeInfo() + "\n名稱:"
+ apple.getName() + "\n價格:" + apple.getPrice() + " 元") : "未獲得伺服器資訊", R.color.red_f);
} catch (Exception e) {
e.printStackTrace();
} finally {
_data.recycle();
_reply.recycle();
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
mService = null;
}
};
複製程式碼
然後就是繫結服務了:
Intent intent = new Intent();
intent.setAction("android.mq.binder.service");
intent.setPackage("org.ninetripods.mq.multiprocess_sever");
bindService(intent, binderConnection, BIND_AUTO_CREATE);
複製程式碼
程式碼也挺簡單,裡面用到的Apple類已經實現了Pacelable介面序列化,程式間傳輸資料就是一個資料序列化和反序列化的過程~
最後貼一下原始碼地址:程式間通訊之Binder,如果對您有幫助,給個star吧,多謝~(注:專案中有兩個專案,請確保先啟動Server端,否則看不到效果)