美文网首页面试题
通过AIDL进行IPC进程间通信

通过AIDL进行IPC进程间通信

作者: 付凯强 | 来源:发表于2019-09-20 00:00 被阅读0次

    1. AIDL是什么

    AIDL即接口定义语言,可以利用它定义客户端与服务均认可的编程接口,以便二者使用进程间通信 (IPC) 进行相互通信。
    在 Android 中,一个进程通常无法访问另一个进程的内存。因此,为进行通信,进程需将其对象分解成可供操作系统理解的原语,并将其编组为可供您操作的对象。编写执行该编组操作的代码较为繁琐,因此 Android 会使用 AIDL 为您处理此问题。
    在我看来,接口定义语言,相当于一个脚本,可以根据某些规则来生成一些代码,从而实现某种功能。
    注意:只有在需要不同应用的客户端通过 IPC 方式访问服务,并且希望在服务中进行多线程处理时,您才有必要使用 AIDL。如果您无需跨不同应用执行并发 IPC,则应通过实现 Binder 来创建接口;或者,如果您想执行 IPC,但需要处理多线程,请使用 Messenger 来实现接口。

    2. 支持的基本数据类型

    // IMyAidlInterface.aidl
    package com.example.testaidl;
    
    // Declare any non-default types here with import statements
    
    interface IMyAidlInterface {
        /**
         * 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);
    }
    

    可以支持的数据类型有

    1. 基本数据类型: int、long、char、boolean、float、double。
    2. String、CharSequence
    3. List: 只支持ArrayList,里面每个元素都必须能够被AIDL支持。
    4. Map: 只支持HashMap,里面每个元素都必须被AIDL支持,包括key和value。
    5. Parcelable: 所有实现了Parcelable接口的对象。
    6. AIDL: 所有的AIDL接口本身也可以在AIDL文件中使用。

    3. 服务端

    提供接口,供其他应用调用的称为服务端。

    • 创建包名com.example.testaidl的Module
    • 创建IAidlServer.aidl
    // IAidlServer.aidl
    package com.example.aidl_server;
    // Declare any non-default types here with import statements
    interface IAidlServer {
       int add(int first,int second);
    }
    

    创建AIDL文件,然后Make Project,生成IAidlServer接口文件

    • 创建Service
    public class IRemoteService extends Service {
    
        private static final String TAG = "IRemoteService";
    
        @Override
        public IBinder onBind(Intent intent) {
            return mBinder;
        }
    
        private IBinder mBinder = new IAidlServer.Stub() {
            @Override
            public int add(int first, int second) throws RemoteException {
                Log.d(TAG, "收到远程请求,输入的参数为" + first + "和" + second);
                return first + second;
            }
        };
    }
    

    IRemoteService供客户端进行绑定,绑定以后会回调一个Binder对象,这个Binder对象和上一篇文章讲到的Binder在实质上一样,都是Binder对象,只是对象的实例方式不一样。

    • 注册Service
            <service
                android:name=".IRemoteService"
                android:exported="true">
                <intent-filter>
                    <action android:name="com.example.aidl"></action>
                </intent-filter>
            </service>
    

    注册Service的同时,约定bindService的action。

    4. 客户端

    调用其他应用接口的被称为客户端。

    • 创建包名为com.example.testaidl的Moudle
    • 把服务端中aidl完整的文件夹拷贝到位于main下面的相同位置
    • 绑定Service
    Intent intent = new Intent();
    intent.setPackage("com.example.aidl_server");
    intent.setAction("com.example.aidl");
    bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
    

    指定包名和action

    • 回调获取服务端Binder对象
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                mAidlServer = IAidlServer.Stub.asInterface(iBinder);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                mAidlServer = null;
            }
        };
    

    onServiceConnected是建立连接时的回调,onServiceDisconnected是断开连接时的回调。

    • 调用服务端方法
                try {
                        int first_num = Integer.parseInt(ed_firtst.getText().toString());
                        int second_num = Integer.parseInt(ed_second.getText().toString());
                        int value = mAidlServer.add(first_num, second_num);
                        Log.d(TAG, "经过远程计算,两个Int值相加的结果为" + value);
                 } catch (RemoteException e) {
                        e.printStackTrace();
                 }
    
    2019-09-19 22:21:49.140 5387-5387/com.example.testaidl D/MainActivity: 经过远程计算,两个Int值相加的结果为9
    

    5. 项目地址

    https://pan.baidu.com/s/1Mx5MW8DuzWHOYC5_V5kYAQ

    6. 后续

    如果大家喜欢这篇文章,欢迎点赞!
    如果想看更多 IPC 方面的文章,欢迎关注!

    相关文章

      网友评论

        本文标题:通过AIDL进行IPC进程间通信

        本文链接:https://www.haomeiwen.com/subject/vigfuctx.html