一、AIDL是什么?
AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言,是跨进程通讯的一种方式。
二、使用步骤
1.服务端创建
在main目录下创建aidl文件夹, 创建包com.xxx.xxx, 创建xx.aidl文件,定义需要的接口,因为需要服务端请求异步数据,所以需要定义个回调接口和数据类bean。
1.1 IDataProvide.aidl 创建
package com.xxx.xxx.aidl;
import com..xxx.xxx.aidl.InPackageInfo;
import com..xxx.xxx.aidl.InTaskCallback;
interface IDataProvider {
void getPackages(String packageName);
void registerCallback(InTaskCallback callback); //注册接口
void unregisterCallBack();//移除接口
}
1.2 InPackageInfo 数据类
package com.xxx.xxx.aidl;
import android.os.Parcel;
import android.os.Parcelable;
public class InPackageInfo implements Parcelable {
private String status = "";
private String startDate = "";
public InPackageInfo (String s, String date){
super();
status = s;
startDate = date;
}
protected InPackageInfo(Parcel in) {
status = in.readString();
startDate = in.readString();
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public static final Creator<InPackageInfo> CREATOR = new Creator<InPackageInfo>() {
@Override
public InPackageInfo createFromParcel(Parcel in) {
return new InPackageInfo(in);
}
@Override
public InPackageInfo[] newArray(int size) {
return new InPackageInfo[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(status);
parcel.writeString(startDate);
}
}
1.3 InPackageInfo.aidl 创建
package com.indibox.tv.aidl;
parcelable InPackageInfo;
1.4 InTaskCallback.aidl 回调创建
package com.xxx.xxx.aidl;
import com.indibox.tv.aidl.InPackageInfo;
interface InTaskCallback {
void getPackages(inout List<InPackageInfo> packageName);
}
1.5 创建服务类 DataProviderService,
package com.xxx.xxx.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class DataProviderService extends Service {
private DataProvider mDataProvider = new DataProvider();
public DataProviderService(){
}
@Override
public IBinder onBind(Intent intent) {
return mDataProvider;
}
public class DataProvider extends IDataProvider.Stub {
private static final String TAG = "DataProvider";
@Override
public void getPackages(String packageName) throws RemoteException {
DataPackagesUtils.getInstance().getPackages(packageName);
}
@Override
public void registerCallback(InTaskCallback callback) throws RemoteException {
DataPackagesUtils.getInstance().setTaskCallback(callback);
}
@Override
public void unregisterCallBack() throws RemoteException {
DataPackagesUtils.getInstance().setTaskCallback(null);
}
}}
注:记得要在AndroidManifest.xml 文件注册DataProviderService,设置action(启动服务的标识)
至此,服务端的准备工作已经完成了,接下来实现客户端。
2.客户端实现
2.1 为了确保不出错,建议直接把服务端的aidl文件夹拷贝
2.2 客户端调用
package com.xxx.aidldemo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.xxx.xxx.aidl.IDataProvider;
import com.xxx.xxx.aidl.InPackageInfo;
import com.xxx.xxx.aidl.InTaskCallback;
import java.util.List;
public class XMAIDLManager {
private Context mContext;
private IDataProvider mDataProvider;
private OnConnectionListener mListener;
public XMAIDLManager(Context context, OnConnectionListener listener) {
mContext = context;
mListener = listener;
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, final IBinder service) {
Log.d("AIDL", "onServiceConnected");
mDataProvider = IDataProvider.Stub.asInterface(service);
try {
mDataProvider.registerCallback(new TaskCallback()); //设置回调
mDataProvider.getPackages("inditvpackage"); //启动请求
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mDataProvider = null;
}
};
class TaskCallback extends InTaskCallback.Stub {
@Override
public void getPackages(List<InPackageInfo> packageName) throws RemoteException {
Log.d("TaskCallback", "getPackages");
//服务端异步请求数据回调接口
}
}
public void startService() {
//启动服务
Intent intent = new Intent();
intent.setAction("你的action");
intent.setPackage("包名");
mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
public void stopService() {
try {
mDataProvider.unregisterCallBack();
mContext.unbindService(connection);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public interface OnConnectionListener {
void onConnection(List<InPackageInfo> packageInfos);
}
}
到此AIDL的跨进程的服务端和客户端就实现了,可以进行数据类bean(可自定义)的传递以及服务端异步回调数据给客户端。
总结
使用过程中主要是数据类型的传递,如果是基本的数据类型可以直接传递,当传递特定对象时需要对这个对应对象进行Parcelable 序列化操作,对应记得传对象参数是,需要标识 in /out/ inout,否则编译会出错。整体AIDL使用还是比较方便的,希望此文章会对大家有帮助。