Android开发,使用AIDL跨进程通信

前言:在某个旧项目中使用到了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跨进程通信的基本用法,有其他需求的话自行改造优化即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值