背景概述

在Android中binder是一种十分重要的过程间通信形式。基于binder实现的过程间通信状态十分多,其中Android的四大组件之一Service,能够用来和binder机制联合,来实现跨过程通信。这种形式就是bindservice,在bindservice这个场景外面,Service作为一个服务端,给调用端也就是client端提供接口。这种形式个别用于Java端和Java端的跨过程通信。上面来具体解说一下这种实现形式。

Service的创立

首先,咱们须要创立一个service,这个service是用来给client端提供接口的。创立service的形式有三种:

扩大binder类

这种形式是当服务端和客户端在同一个过程时应用。因而,这种形式并不具备跨过程的能力,本文就不具体讲述了。

应用Messenger

这种形式可能实现跨过程通信。次要特点是,它将申请放入一个队列中,服务端不须要进行线程平安设计。这种形式其实在我的项目开发中应用的并不多。本文也不具体讲述了。

备注:
对于上述两种形式具体能够参考:developer.android.com/guide/compo…

应用AIDL

AIDL是Android提供的一种不便让开发者基于binder来实现跨过程通信的一种工具。它的特点是反对客户端同时并发拜访,所以如果你的服务设计为AIDL的形式,那么你须要思考线程平安的设计。上面来具体说下这种形式:

创立.aidl文件

.aidl文件须要开发者本人依照语法规定来定义。提供服务的服务端和绑定服务的客户端都须要蕴含.aidl源码文件。一般来说会定义两个aidl文件,一个是给client调用service提供接口定义,另外一个是给service回调client提供接口定义。

实现AIDL中定义的接口

AIDL定义的接口,必须在service端给出每个接口的具体实现。

向client端公开接口

将实现了AIDL接口的实例,通过onBind()接口返回给client端,这样client端能力通过这个实例调用AIDL的接口实现。

备注:
具体实现代码参考:client端源码 github.com/jiantengfei… service端源码 github.com/jiantengfei…
相干文章参考:developer.android.com/guide/compo…

应用AIDL的技术要点

通过IPC调用传递objects

在IPC调用中,须要传递函数型参给对端。在AIDL中,反对以下数据类型的传递:
Java语言中的原语类型(int、long、char、boolean等)
String、CharSequence、List(对端的接收数据是ArrayList)、Map(对端的接收数据是HashMap)
另外还反对自定义对象的IPC传输,然而开发者必须本人实现自定义对象的序列化。在AIDL中是将自定义对象实现Parcelable接口,并给出接口实现,来实现对象的序列化的。
在Android 10以上的版本,能够间接在AIDL中定义Parcelable对象。AIDL工具在编译时能够帮忙开发者主动生成对应的对象的序列化代码。参考如下:

package android.graphics;// Declare Rect so AIDL can find it and knows that it implements// the parcelable protocol.parcelable Rect {    int left;    int top;    int right;    int bottom;}复制代码

如果想要本人来实现的话,首先新增一个Rect.aidl文件

package android.graphics;// Declare Rect so AIDL can find it and knows that it implements// the parcelable protocol.parcelable Rect;复制代码

再定义Rect这个类的具体实现:

import android.os.Parcel;import android.os.Parcelable;public final class Rect implements Parcelable {    public int left;    public int top;    public int right;    public int bottom;    public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {        public Rect createFromParcel(Parcel in) {            return new Rect(in);        }        public Rect[] newArray(int size) {            return new Rect[size];        }    };    public Rect() {    }    private Rect(Parcel in) {        readFromParcel(in);    }    public void writeToParcel(Parcel out, int flags) {        out.writeInt(left);        out.writeInt(top);        out.writeInt(right);        out.writeInt(bottom);    }    public void readFromParcel(Parcel in) {        left = in.readInt();        top = in.readInt();        right = in.readInt();        bottom = in.readInt();    }    public int describeContents() {        return 0;    }}复制代码

办法中带有Bundle类型参数

// IRectInsideBundle.aidlpackage com.example.android;/** Example service interface */interface IRectInsideBundle {    /** Rect parcelable is stored in the bundle with key "rect" */    void saveRect(in Bundle bundle);}复制代码

在service端解析Bundle之前,须要显示在Bundle中setClassLoader。

private final IRectInsideBundle.Stub binder = new IRectInsideBundle.Stub() {    public void saveRect(Bundle bundle){        bundle.setClassLoader(getClass().getClassLoader());        Rect rect = bundle.getParcelable("rect");        process(rect); // Do more with the parcelable.    }};复制代码

总结

本文次要介绍了Android中,应用binder和binderservice这种形式,来实现Java端和Java端跨过程通信的形式。并简略介绍了下应用AIDL工具的关键技术点。