- 新建 aidl 文件夹,在其中创建接口 aidl 文件以及实体类的映射 aidl 文件
- 如果需要访问自定义对象,创建要操作的实体类,实现 Parcelable 接口
- 创建接口aidl文件,定义方法
- 客户端和服务端相同的aidl文件
- 创建 Service,在service中创建上面生成的 Binder 对象实例,实现aidl接口定义的方法,处理客户端的请求;在onbind方法将binder返回回去
- 在AndroidManifest配置service,将service暴露出去
- 实现 ServiceConnection 接口,并在其中拿到aidl类
- 绑定服务
- 通过aidl类调用其中的方法
创建Request.aidl文件
package com.example.aidl;
parcelable Request;
创建Response.aidl文件
package com.example.aidl;
parcelable Response;
package com.example.aidl;
// Declare any non-default types here with import statements
import com.example.aidl.Request;
import com.example.aidl.Response;
import com.example.aidl.CallBack;
interface IpcService{
Response send(in Request request);
void register(CallBack callback);
void unregister(CallBack callback);
}
3、回调机制。主要是客户端向服务端发送数据的同时需要服务端返回数据给客户端。首先在服务端创建CallBack.aidl文件。并同时在IpcService.aidl文件中添加注册回调方法和解除回调方法(如上图)。
package com.example.aidl;
// Declare any non-default types here with import statements
interface CallBack{
void onSuccess(String result);
void onFailed(String errorMsg);
}
4、创建service来响应客户端的请求。创建IpcRemoteService.java文件。创建Binder对象,并在onBind()方法返回回去。实现aidl接口文件里的请求方法,根据request.msgType实现不同的业务逻辑。
class RemoteBinder extends IpcService.Stub {
@Override
public Response send(Request request) throws RemoteException {
String msgContent = request.msgContent;
Response response = new Response();
//这里根据msgType处理不同的业务逻辑
switch (request.msgType) {
case Request.MSG_TYPE_0:
Log.d(TAG, msgContent);
response.setResult("return success");
//有返回的可以不用这个回调
dispatchResult(true, msgContent);
break;
case Request.MSG_TYPE_1:
break;
case Request.MSG_TYPE_2:
break;
case Request.MSG_TYPE_3:
break;
case Request.MSG_TYPE_4:
break;
default:
break;
}
return response;
}
这里需要注意的是如果你的java文件放在src/main/java目录下,则你的java目录下的包名必须和aidl目录下的包名一致,如果你的java文件放在src/main/aidl目录下,则必须在app的build.gradle文件里面加入如下代码:
sourceSets {
main {
java.srcDirs = ["src/main/java", "src/main/aidl"]
}
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
String packageName = null;
String[] packages = IpcRemoteService.this.getPackageManager().
getPackagesForUid(getCallingUid());
if (packages != null && packages.length > 0) {
packageName = packages[0];
}
Log.d(TAG, "onTransact: " + packageName);
if (!PACKAGE_SAYHI.equals(packageName)) {
return false;
}
return super.onTransact(code, data, reply, flags);
}
public void bindService() {
Intent serviceIntent = new Intent();
serviceIntent.setAction(BIND_SERVICE_ACTION);
final Intent mIntent = new Intent(achieveExplicitFromImplicitIntent(mContext, serviceIntent));
isBind = mContext.bindService(mIntent, mConnection, Context.BIND_AUTO_CREATE);
Log.d(TAG, "bindService");
}
public Intent achieveExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
Log.d(TAG, "packageName = " + packageName);
Log.d(TAG, "className = " + className);
ComponentName component = new ComponentName(packageName, className);
Intent explicitIntent = new Intent(implicitIntent);
explicitIntent.setComponent(component);
return explicitIntent;
}
这里主要是通过ServiceConnection来监控远程服务的状态的。服务连接成功会触发onServiceConnected方法,服务断开连接或者崩溃会触发onServiceDisconnected方法,我们在这里重新绑定服务。
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
ipcService = IpcService.Stub.asInterface(service);
Log.d(TAG, "onServiceConnected");
if (ipcService == null) {
Log.i(TAG, "mStudentService == null");
return;
}
try {
//设置死亡代理
ipcService.asBinder().linkToDeath(mDeathRecipient, 0);
if (mCallback != null) {
Log.i(TAG, "mCallback != null");
ipcService.register(mCallback);
} else {
Log.i(TAG, "mCallback == null");
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "client onServiceDisconnected");
ipcService = null;
// 重新绑定服务
bindService();
}
};
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
if (ipcService == null) {
return;
}
//解除死亡代理
ipcService.asBinder().unlinkToDeath(mDeathRecipient, 0);
ipcService = null;
//重新绑定服务
bindService();
Log.i(TAG, "binderDied, bindService again");
}
};
public Response sendRequest(Request request) {
Response response = null;
if (ipcService != null) {
try {
response = ipcService.send(request);
} catch (RemoteException e) {
e.printStackTrace();
}
}
return response;
}
public void unBindSevice() {
if (isBind) {
mContext.unbindService(mConnection);
isBind = false;
ipcService = null;
Log.d(TAG, "unbindService");
}
}