也许你从不曾了解过安卓AIDL

事先声明,本文所有说法均是临时起意,没有完整代码给予参考

AIDL作用

AIDL(Android Interface Definition Language)是一种用于定义和实现跨进程通信接口的语言。它是 Android 系统中用于进程间通信(IPC)的一种机制,允许一个进程向另一个进程发送请求并获取响应。

从介绍中可与看到,AIDL是被用作跨进程传输数据的一种方式。

有很多人说我开发安卓几年就没用个AIDL,其实也正常,大多APP只有一个进程,用不上这玩意。一个APP里多个进程的操作多数用来做些花里胡哨的操作,比如进程守护、加大内存。但是这里叔劝你一句,没必要,叔怕你把握不住。

回归本质,就让AIDL做它该做的事情,跨进程通信,跨APP通信

AIDL有哪些竞品(我想列哪些就列哪些)

  • Socket
  • 文件共享
  • startActivity、startService、BroadcastReceiver、ContentProvider

为什么选用AIDL

  • 跟Socket和文件共享相比,实现简单。(虽然在很久很久以前,AIDL是手动实现的)
  • 跟四大组件相比,异步回调简单,这里也许很多人虽然用到过,但是很少意识到四大组件的异步回调

AIDL别人都怎么用

  1. 定义个aidl文件,声明几个方法
  2. 再搞个Service,在onBind里返回个binder对象
  3. 在某个方法里调用bindService,通过ServiceConnection回调来获取aidl对象

这么用行不行,行,大家都这么用绝对是可以的。 但是方便吗?一点也不方便。 我这里说一句,只能异步的操作都不方便,代码还丑,谁赞成谁反对。 谁反对站出来 。 所以题外话, DataStore NO ,协程 YES。

好了,多余的题外话说完了,diss完别人,到你这又该怎么用。

这种做法我推荐给你

ContentProvider的结果是同步返回的,可以先这样,再那样:

1.自定义BinderCursor继承MatrixCursor

java 复制代码
import android.database.MatrixCursor;
import android.os.Bundle;
import android.os.IBinder;

public class BinderCursor extends MatrixCursor {
    private static final String KEY_BINDER = "binder";

    private final Bundle mBinderExtra = new Bundle();

    public BinderCursor(IBinder binder) {
        super(new String[]{"service"});
        if (binder != null) {
            mBinderExtra.putBinder(KEY_BINDER, binder);
        }
    }

    @Override
    public Bundle getExtras() {
        return mBinderExtra;
    }
}

2.自定义AidlCoreProvider继承ContentProvider

kotlin 复制代码
class AidlCoreProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        return true
    }

    override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
        //这里可以根据条件判断返回具体某个Aidl实现类
        val binder = Aidl实现类()
        return BinderCursor(binder)
    }

    override fun getType(uri: Uri): String? {
        return null
    }

    override fun insert(uri: Uri, values: ContentValues): Uri? {
        return null
    }

    override fun delete(uri: Uri, selection: String, selectionArgs: Array<String>): Int {
        return 0
    }

    override fun update(uri: Uri, values: ContentValues, selection: String, selectionArgs: Array<String>): Int {
        return 0
    }
}

3.获取aidl对象这么搞

java 复制代码
private aidl对象 parseAidlService() {

        try {
            final Uri aidlUri = Uri.parse("content://********");
            final ContentResolver resolver = context.getContentResolver();
            final Cursor cursor = resolver.query(aidlUri , null, null, new String[]{这里可以搞个条件参数}, null);
            aidl对象 aidlService = null;
            if (cursor != null) {
                aidlService = aidl对象.Stub.asInterface(getBinder(cursor));
                cursor.close();
            }
            if (aidlService != null) {
                return aidlService;
            }
        } catch (Exception ignored) {

        }

        return null;
    }


private static IBinder getBinder(Cursor cursor) {
        Bundle extras = cursor.getExtras();
        return extras.getBinder("binder");
    }

科普阶段

  • aidl文件方法声明时是可以指定标号的,比如下面这种写法。也许极少数人意识到过,aidl文件的方法是存在标号的,默认标号以定义方法的顺序为依据,赋值后则赋予的值代表标号。 这在Server和Client中aidl文件有区别时,尤其需要注意,我遇到过有人加aidl方法直接加在文件中间。 aidl方法的执行主要依靠这个标号,如果标号和方法对不上则会产生问题,会产生什么问题当做叔对你的考验。
aidl 复制代码
interface IAidlInterface {
    void basicTypes(int anInt) =1;
}
  • 什么时候用in、out、inout,client端能改server端不能改的参数用in,反过来用out,两端都想改的用inout。 实际不需要记,叔教你,先什么都不加,编译不过会报错的,报错了就加inout,这和直接用public一样,等到你真正明白之后,再去使用最小限度吧。

  • 什么时候用oneway,大多数用不上。不关心server端执行情况的就加这个。但是联系生活,就算真的不关心,也没必要表现出来,我们假装关心一下,也就是不加oneway。

  • 方法数据传输量大怎么办,aidl跨进程通信时有数据量限制,太大了受不了。 题外话,为什么要限制大小,限制大小也是限制时间,数据量大传输时间就长,假装aidl实现是内存共享,空间时间就那么大那么多,不能让你全占了。就跟去医院挂号一样,就一个医生让你用一天,别人看不了病了。 回归正题,数据量就是大怎么办,也能办,分片传输。 分片实现类参照类android.content.pm.ParceledListSlice或者android.content.pm.StringParceledListSlice实现,它可以分片传输List,是隐藏类,但是可以用,可以使用这个带隐藏类的库。

相关推荐
Dovis(誓平步青云)4 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
晚风叙码6 小时前
MySQL 数据类型详解:从数值到字符串,一篇讲透
android·mysql·adb
传奇开心果编程6 小时前
【Compose Multiplatform 跨端开发学与练】第3课 布局与组件
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程9 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
传奇开心果编程10 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
传奇开心果编程10 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程11 小时前
【Compose Multiplatform 跨端开发学与练】第6课 状态管理与架构
android·学习·ui·ios·架构·kotlin·composer
事圆则缓11 小时前
Android AOSP 定制常见概念:源码目录、系统镜像与刷机流程
android
传奇开心果编程11 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer
supabc12311 小时前
Celium:连接 Windows、Mac、Linux 与 Android,让远程访问和设备管理更简单
android·linux·windows·macos·远程访问·网络管理·celium