前言
想想一下這樣一種場景,我們在模塊化開發某個功能的時候,我們不想吧核心的代碼曝露出去,而且也沒辦法曝露出某些代碼。例如:某第三方要提供給一些功能給外部。在比如,上層APP的開發者需要用到某手機專屬的某一功能A,但該手機廠商又沒有對外發布sdk(或者jar包)。本文介紹的AIDL機制理論上可以解決該問題。
創建Android Studio Project
這裏不描述是如何step by step創建 project,最終結果如下圖所示。其中aidl 是module名稱,在下一節介紹
創建AIDL module
對應的module創建成功之後,創建一個AIDL文件,一個service文件;在service文件中實現AIDL的接口調用
IMyAidlInterface.aidl
// IMyAidlInterface.aidl
package cp.com.aidl;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
String getStr();
boolean setStatus(int aInt);
}
MyAIDLService.java
package cp.com.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyAIDLService extends Service {
private static final String TAG=MyAIDLService.class.getSimpleName();
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//throw new UnsupportedOperationException("Not yet implemented");
return mBinder;
}
private final IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
@Override
public String getStr() throws RemoteException {
Log.e(TAG,"this from AIDL service ...getStr..");
return TAG;
}
@Override
public boolean setStatus(int aInt) throws RemoteException {
Log.e(TAG,"this from AIDL service ...setStatus..="+aInt);
return (aInt%2 == 0);
}
};
}
需要注意的一點是,在實現module的aidl代碼時,完成aidl代碼的編寫之後需要講module build下。否則可能會出現找不到包名的情況。
好,至此我們講AIDL的實現部分使用Android studio 的module來實現;接下來我們在app中來調用對應的服務。
客戶端調用AIDL服務
創建客戶端aidl文件
首先在/path/to/application/app/src/main目錄下創建一個aidl目錄(名字任意)
接着創建一個同.aidl
文件相同的包名,並將aidl文件拷貝到該包名下;例如這裏的cp.com.aidl
綁定service
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MyAIDLService.class);
bindService(intent,conn,Service.BIND_AUTO_CREATE);
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mAIDLService = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mAIDLService = null;
}
};
private void updateTextView(){
String str = null;
boolean status = false;
try {
str = mAIDLService.getStr();
status = mAIDLService.setStatus(count);
count++;
} catch (RemoteException e) {
e.printStackTrace();
}
aidlTextView.setText(str+status);
}
確認APP同 module的依賴關係
編譯運行
後話
IPC用處還是多多的。。
後續,當有某一功能即是必須要曝露給第三方,但是又不能給核心代碼,編譯jar包扔進APP又太繁瑣。這裏提供了一個可選擇的方案