Android studio 使用aidl和service進行程序間通訊
一.概述
Android的Binder機制可以進行程序間通訊,但是Servicemanager這個類不公開,也就是我在自己的應用程式中無法使用Servicemanager的addService將我們自己定義的service註冊到binder中去,也無法通過getService獲取到對應的Service,那麼在我們的應用程式要如何來進行程序間通訊呢?利用aidl檔案和Service就可以進行通訊了.
二.編寫AIDL檔案
在android studio按如上方法就可以建立aidl檔案,在aidl檔案中定義相關的功能,比如我在這裡就定義了一個getString 方法:
將編寫好的aidl檔案編譯就會生成同名的.java檔案.為什麼生成的aidl檔案可以進行程序間通訊呢,因為它會自動幫我們生成對應的Binder子類stub和對應的proxy類,至於這2個類是做什麼的,這就涉及到了binder的知識,binder知識不是一下可以說清楚的,只能靠自己去研究了.
三.編寫Service
public class WatchDogService extends Service {
public IBinder onBind(Intent intent) {
return new MyBind();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onCreate() {
super.onCreate();
}
//這個類就是繼承自aidl編譯後生成的對應的.java件中的Stub類,它是Binder的子類
class MyBind extends test.Stub{
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
/**重寫 getString 方法
@Override
public String getString(String str) throws RemoteException {
return "遠端服務返回的資料:"+str;
}
}
}
四.將servie註冊到AndroidManifest.xml中
<service android:name="com.betterda.test3.actiivty.WatchDogService">
<intent-filter>
<action android:name="com.lypeer.aidl"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
五.在另外一個應用程式中繫結servie
上面的service就定義在com.betterda.test3這個包名的應用程式中,接下來我在com.betterda.test2這個包名的應用程式中通過bindService來啟動WatchDogService,然後呼叫test介面中定義的getString方法可以獲取到WatchDogService返回的資訊了,下面的程式碼就是bindservice
Intent intent = new Intent();
intent.setAction("com.lypeer.aidl");
intent.setPackage("com.betterda.test3");
if (!isBind) {
//因為是在另外一個程式的servie,所以只能通過action和package來繫結servie
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
isBind = true;
//繫結成功以後,會返回在Service的onbind方法中返回的binder物件,我們在WatchDogService的onbind方法中返回就是new MyBind(),它是test.Stub類
//所以我們在這裡可以得到Stub的Proxy物件
mTest = test.Stub.asInterface(service);
try {
//通過proxy的代理物件就可以呼叫getstring方法
String string = mTest.getString("你好");
Toast.makeText(MainActivity.this, string,0).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBind = false;
Log.e(getLocalClassName(), "service disconnected");
}
};
在上面的程式碼中我們將繫結servive返回binder轉換來test.Stub的Proxy物件,然後才能呼叫在test介面中定義的方法,所以在這個com.betterda.test2應用程式也要定義一個同樣功能的aidl檔案,這個只要將com.betterda.test3中定義的aidl檔案拷貝過來,然後重新編譯就會自定生成了,執行com.betterda.test2就可以看到getString返回:遠端服務返回的資料:你好
六.總結
想要在程序間通訊使用都是Binder機制,aidl和bindService就為了方便開發者在自己的應用程式中使用Binder機制來通訊,bindService就是代替了ServiceManager的addService來向Binder驅動註冊服務.