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文件也要注意一下:
android:name=".MyService" android:enabled="true" android:exported="true">
这样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可以写在类库中!