Android AIDL

 

目录

1. 简介

2. 定义

3. 编译

4. 说明


 

1. 简介

Android AIDL 作为跨进程通信的一种可选方式;

最近再整理以前写过的代码中,觉得这玩意还是值得整理一下的,有时间了拿出来写写,简单记录一下;

 

2. 定义

在Android Studio 中新建AIDL 文件,如下图所示

注意AIDL 的编写方式,

  1. 文件格式为,aidl;
  2. package 包声明要和实际目录(rootProject/.../aidl/...)对应起来;
  3. 尽量使用基础类型和API 中已有对象或多态;

 

3. 编译

这个没啥好说的,使用Android Studio -> Build -> Make Module 'XXX' 即可,此处的‘XXX’ 为项目Modules research-common;

 

此时,你的项目Modules generateJava 目录下,如图所示:

这个是Android 视图,如果你所用的Android Sutdio 中没有看到,切换到Project 视图,目录在./rootProject/.../build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/.../aidl/...

如下图所示:

 

4. 说明

如下图所示:

 

AIDL 编译后自动生成的结构差不多都和上图长的结构一致;

简明说一下:

1. 自己定义的AIDL 接口为IMessageManagere,编译后为IMessageManager extend android.os.IInterface;这个IInterface 接口为系统提供的接口类,如下:

package android.os;

/**
 * Base class for Binder interfaces.  When defining a new interface,
 * you must derive it from IInterface.
 */
public interface IInterface
{
    /**
     * Retrieve the Binder object associated with this interface.
     * You must use this instead of a plain cast, so that proxy objects
     * can return the correct result.
     */
    public IBinder asBinder();
}

简单理解为,AIDL 通过IPC 方式中的IBinder(Binder设备文件)进行跨进程交互;如果我想和你交流,我得先跟你是同类,然后我说的和你说的是同类语言才行;

2. 注意到由于是IPC 方式得交互,所有自己定义得接口方法都带有android.os.RemoteException 声明,如下图所示:

3. 然后核心部分来了,IMessageManager.Stub 作为远程Binder 得委托对象,有关Binder和IBinder 的底层细节暂不讨论,需要C/C++ 层知识,我看的有时候都蒙圈了,水平有限,怕误人子弟嘞;

需要注意的大致节凑如下几点方法:

  • IBinder#queryLocalInterface();
  • IMessageManager.Stub.Proxy();
  • Binder#attachInterface();
  • IMessageManager.Stub#onTransact();
  • IBinder#transact();

我们只需要简单看下如下关键点,

        /**
         * Cast an IBinder object into an com.xxx.aidl.IMessageManager interface,
         * generating a proxy if needed.
         */
        public static com.xxx.aidl.IMessageManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.xxx.aidl.IMessageManager))) {
                return ((com.xxx.aidl.IMessageManager) iin);
            }
            return new com.xxx.aidl.IMessageManager.Stub.Proxy(obj);
        }

4. 使用ServiceConnection 对象进行连接进行,所有远程服务都可通过此处的IBinder 句柄进行,如下所示:

    protected ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IMessageManager messageManager = IMessageManager.Stub.asInterface(service);
            try {
                String value = "" + System.currentTimeMillis();
                int count = (int) (Math.random() * 100);
                for (int i = 0; i < count; i++) {
                    messageManager.updateMsg(value + i);
                }
                String msg = messageManager.getMsg();
                Log.d(TAG, "the current(sum:" + count + ") obtain msg(" + value + ") is " + msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "the current(ComponentName:" + name.getShortClassName() + ")");
        }
    };

5. 通过Context#bindService()和Context#unbindService() 建立连接和解绑连接;

        Intent intent = new Intent(this, MessageManagerService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);


        unbindService(serviceConnection);

 

6. 在Manifest.xml 中记得声明即可;

        <service
            android:name=".service.MessageManagerService"
            android:process=":remote" />

 

 

简单记录就先这些吧,还是需要平时写代码的过程中,进行多思考,多总结;

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值