前言:在某个旧项目中使用到了aidl进行跨进程通信,这里把他的实现流程简单地整理一下方便有相同需求的小伙伴参考。
一、开启一个单独进程的Service
方法很简单,在 manifest 文件中注册时指定 process 名称即可
<service
android:name=".Other.Service.AidlService"
android:process=":aidl"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.lxt.single_module.Aidl.MyAidl" />
</intent-filter>
</service>
二、定义aidl文件
1. 启用aidl
需要在 build.gradle 的 buildFeatures 字段中启用 aidl
buildFeatures {
aidl = true // 启用 aidl
}
2. 创建aidl目录
3. 创建aidl文件
4. 定义aidl接口
这里先用一个简单的例子作为参考
interface MyAidl {
void sendMessage(String message);
}
定义完成之后记得编译一下
三、在Activity与Service中实现
1. Service中实现
实现 MyAidl.Stub 对象并在onBind方法返回
private final MyAidl.Stub mBinder = new MyAidl.Stub() {
@Override
public void sendMessage(String message) throws RemoteException {
Log.e(TAG, "received aidl msg from activity: "+message);
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
2. Activity中实现
private var aidlService: MyAidl? = null
private var aidlServiceRunning = false
private val aidlServiceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, binder: IBinder) {
aidlService = MyAidl.Stub.asInterface(binder)
aidlServiceRunning = true
loge("绑定AIDL服务")
}
override fun onServiceDisconnected(name: ComponentName) {
aidlService=null;aidlServiceRunning = false;loge("解绑AIDL服务")
}
}
fun bindMQTTService(){
val intent = Intent(this, AidlService::class.java)
bindService(intent, aidlServiceConnection, Context.BIND_AUTO_CREATE)
}
3. 通信
在Activity中绑定Service成功后使用aidl文件中定义的方法即可
viewBinding.send.setOnClickListener {
aidlService?.let {
it.sendMessage("测试文本")
}
}
在Service中实现的方法处理收到的数据
@Override
public void sendMessage(String message) throws RemoteException {
Log.e(TAG, "received aidl msg from activity: "+message);
}
以上就是一个简单的通过aidl传输String类型数据实现例子,此外还有双向互通和传输自定义对象的例子有空再补充
四、补充
1. 传输自定义对象
定义需要传递的对象并且实现 Parcelable 接口
public class AidlEntity implements Parcelable {
public String name;
public int age;
public AidlEntity(){
}
public AidlEntity(Parcel in) {
name = in.readString();
age = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<AidlEntity> CREATOR = new Creator<AidlEntity>() {
@Override
public AidlEntity createFromParcel(Parcel in) {
return new AidlEntity(in);
}
@Override
public AidlEntity[] newArray(int size) {
return new AidlEntity[size];
}
};
}
同时创建对应的aidl对象文件
parcelable AidlEntity;
定义aidl接口,记得要导入自定义的对象并且重新编译一下
package com.lxt.single_module;
import com.lxt.single_module.AidlEntity;
interface MyAidl {
void sendMessage(String message);
void sendPerson(in AidlEntity person);
}
在Binder中补充新增的方法
private final MyAidl.Stub mBinder = new MyAidl.Stub() {
@Override
public void sendMessage(String message) throws RemoteException {
Log.e(TAG, "received aidl msg from activity: "+message);
}
@Override
public void sendPerson(AidlEntity person) throws RemoteException {
Log.e(TAG, "收到自定义对象: "+person.name+" / "+person.age);
}
};
传输自定义对象
viewBinding.send.setOnClickListener {
aidlService?.let {
// it.sendMessage("测试文本")
val person = AidlEntity().apply {
name = "lxt"
age = 24
}
it.sendPerson(person)
}
}
2. 双向互通
创建aidl回调文件
定义回调方法
import com.lxt.single_module.AidlEntity;
interface MyCallback {
void onServiceMessage(String msg);
void onServiceEntity(in AidlEntity person);
}
定义aidl接口并重新编译
package com.lxt.single_module;
import com.lxt.single_module.MyCallback;
import com.lxt.single_module.AidlEntity;
interface MyAidl {
void sendMessage(String message);
void sendPerson(in AidlEntity person);
void registerCallback(MyCallback callback);
void unregisterCallback(MyCallback callback);
}
在Binder中补充新增的方法并获取RemoteCallbackList对象
private RemoteCallbackList callbacks = new RemoteCallbackList<MyCallback>();
private final MyAidl.Stub mBinder = new MyAidl.Stub() {
@Override
public void sendMessage(String message) throws RemoteException {
Log.e(TAG, "received aidl msg from activity: "+message);
}
@Override
public void sendPerson(AidlEntity person) throws RemoteException {
Log.e(TAG, "收到自定义对象: "+person.name+" / "+person.age);
}
@Override
public void registerCallback(MyCallback callback) throws RemoteException {
callbacks.register(callback);
}
@Override
public void unregisterCallback(MyCallback callback) throws RemoteException {
callbacks.unregister(callback);
}
};
发送数据
private void sendMessage(String msg){
try {
int callbackCount = callbacks.beginBroadcast();
if(callbackCount>0){
for (int i = 0; i < callbackCount; i++) {
MyCallback callback = (MyCallback) callbacks.getBroadcastItem(i);
if(callback!=null){callback.onServiceMessage(msg);}
}
} else {
Log.e(TAG, "回调数量为0");
}
callbacks.finishBroadcast();
} catch (Exception e){
e.printStackTrace();
}
}
private void sendPerson(AidlEntity person){
try {
int callbackCount = callbacks.beginBroadcast();
if(callbackCount>0){
for (int i = 0; i < callbackCount; i++) {
MyCallback callback = (MyCallback) callbacks.getBroadcastItem(i);
if(callback!=null){callback.onServiceEntity(person);}
}
} else {
Log.e(TAG, "回调数量为0");
}
callbacks.finishBroadcast();
} catch (Exception e){
e.printStackTrace();
}
}
在Activity中注册数据接收监听
private var aidlService: MyAidl? = null
private var aidlServiceRunning = false
private val callback = object : MyCallback.Stub(){
override fun onServiceMessage(msg: String?) {
loge("收到 Service 消息: $msg")
}
override fun onServiceEntity(person: AidlEntity?) {
person?.let {
loge("收到 Service 对象: ${it.name + " / "+it.age}")
}
}
}
private val aidlServiceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, binder: IBinder) {
aidlService = MyAidl.Stub.asInterface(binder)
aidlServiceRunning = true
loge("绑定AIDL服务")
try {
aidlService?.registerCallback(callback) // 注册消息接收回调
}catch (e:Exception){e.printStackTrace()}
}
override fun onServiceDisconnected(name: ComponentName) {
try {
aidlService?.unregisterCallback(callback)
}catch (e:Exception) {e.printStackTrace()}
aidlService=null;aidlServiceRunning = false;loge("解绑AIDL服务")
}
}
完成,文章仅仅只是展示了aidl跨进程通信的基本用法,有其他需求的话自行改造优化即可