AIDL
Android使用AIDL來實現進程間的通訊;
最簡單的進程,兩個APP(APP1(app_server) , APP2(app_client)),這裏app_server可以看作一個進程 , app_client也可以看作一個進程; 所以AIDL可以來實現兩個APP之間的通訊;
先來寫一個最簡單的AIDL進程間的通訊;
app_client要調用app_server中的數據,首先app_server先把數據暴露出去;
app_server端:
1、新建AIDL文件;
輸入名稱後 , 會自動創建一個aidl結尾的文件;
// Declare any non-default types here with import statements
interface ICbAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
basicTypes文件只是告訴你參數的基礎類型 , 直接刪了;然後創建一個新的方法;
interface ICbAidlInterface {
String getName();
}
2、創建完成AIDL文件後 , 重新構建一下項目(sycn project)會自動生成一個新文件,如下
然後新建一個Service,新建一個內部類繼承AIDL中的Stub類 , 然後重寫AIDL中的方法;
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return new CbBinder();
}
class CbBinder extends ICbAidlInterface.Stub{
@Override
public String getName() throws RemoteException {
return "CCB呀";
}
}
}
AndroidManifest文件也要注意一下:
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.cuichen.mvvmdemo.service"/>
</intent-filter>
</service>
這樣app_server中的aidl已經完成了;
app_client端:
app_client要調用app_service的getName()方法;
1、app_service中的aidl文件原封不動的複製過來 , 注意包名也和app_service中的一樣;
2、在Activity中使用;綁定service , onServiceConnected方法中通過ICbAidlInterface.Stub.asInterface(iBinder)實例,然後就可以調用aidl中的getName()方法啦;
private ICbAidlInterface iCbAidlInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_m);
findViewById(R.id.btClick2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Log.i("ccb", "onClick: "+iCbAidlInterface.getName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
Intent intent = new Intent();
intent.setAction("com.cuichen.mvvmdemo.service");
intent.setPackage("com.cuichen.mvvmdemo");
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
iCbAidlInterface = ICbAidlInterface.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}, Service.BIND_AUTO_CREATE);
}
這樣就可以完成實現進程間的通訊了 , APP2調用APP1中的方法;
注意:出現'Process 'command 'D:\AndroidStudio\sdk\build-tools\29.0.0\aidl.exe'' finished with non-zero exit value -1073741819' ,類似這樣的報錯,查看項目中的buildToolsVersion是否都一致 , 主Moudle和其它類庫的版本號要保持一致;
AIDL使用自定義類型:
除了已定義的基礎類型 , aidl還可以傳遞自定義類型,前提是該類必須序列化(Parcelable);下面是APP1 的 代碼和結構;
注意:自定義類型 java文件夾下的.java文件和 aidl文件夾下的.aidl文件 , 要保證包名相同;
AidlBean.java 如下:
public class AidlBean implements Parcelable {
private String name;
private Integer age;
......
}
AidlBean.aidl 如下:
// AidlBean.aidl
package com.cuichen.mvvmdemo;
parcelable AidlBean;
ICbAidlInterface.aidl 如下:
package com.cuichen.mvvmdemo;
import com.cuichen.mvvmdemo.AidlBean;
interface ICbAidlInterface {
String getName();
AidlBean getBean();
}
完成後 , 把新增和修改的文件複製到第二個(APP2)項目;
APP2(app_client)結構如下:
注意:包名要和APP1中的包名保持一致:
AIDL可以寫在類庫中!