快速掌握aidl

作者 : 开心源码 本文共3277个字,预计阅读时间需要9分钟 发布时间: 2022-05-12 共229人阅读

aidl是Android中用于跨进程通讯的语言。当需要在项目中使用多个进程,可以使用此技术实现进程间通信。那么如何使用aidl呢?

1. 创立aidl文件

在src/main目录下面右键创立aidl文件,androidStudio会给我们自动生成相应的目录和示例文件。

自动生成的目录和文件

2. 创立需要的传输的实体类bean

需要知道 : aidl中支持java的8中基础数据类型和Charsequence、String、List、Map。引用对象类型需要序列化,且仅支持parcelable方式的序列化。

public class Book implements Parcelable {    private String name;    private float price;    public Book(Parcel in) {        this.name = in.readString();        this.price = in.readFloat();    }    public static final Creator<Book> CREATOR = new Creator<Book>() {        @Override        public Book createFromParcel(Parcel in) {            return new Book(in);        }        @Override        public Book[] newArray(int size) {            return new Book[size];        }    };    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeString(name);        dest.writeFloat(price);    }}
3. 创立公告实体类的aidl文件

第二点说了aidl只支持固定的几种数据类型,对于引用类型,假如想支持的话,需要创立对应的xxx.aidl的文件,而后在里面公告该实体类。一个aidl文件对应一个实体类。必需这样,才能正常编译运行程序。比方在Book.aidl文件中公告Book对象
需要知道:aidl文件中,假如要访问其余文件对象,需要import 该文件包名。即便他们在同一个包下(这个和kotlin、dart语言相似,一个文件相当于包的访问权限)

// Book.aidlpackage com.example.bangbangqiu.bluetoothapp;// Declare any non-default types here with import statementsimport com.example.bangbangqiu.bluetoothapp.Book;parcelable Book;
4. 修改IMyAidlInterface.aidl文件

这个文件也是最关键的文件。在这个接口文件中公告方法,它作为服务进程与用户端进程之间的桥梁。

公告的方法和接口方法公告一样 只要要 返回类型 + 方法名的格式。
会看到 参数中有带关键字in(定向tag)。在aidl中方法参数 可以用 in out inout修饰,in表示数据由用户端流向服务器端,out反之,inout数据双向都可传输。

interface IMyAidlInterface {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */    List<Book> getBooks();    void addBook(in Book book);    void feedBack();}

到此aidl部分已经完成了,编译之后,会在build/generate/source/aidl文件下面看到ide自动生成的aidl的实现类。下面就需要写用户端和服务端的代码逻辑了

5. 创立服务进程

创立service并使其在名为remote的进程中运行

public class AIDLService extends Service {    List<Book> books = new ArrayList<>();    IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() {        @Override        public List<Book> getBooks() throws RemoteException {            return books;        }        @Override        public void addBook(Book book) throws RemoteException {            books.add(book);        }        @Override        public void feedBack() throws RemoteException {            Log.d("AIDLService", "feedBack: is running");        }    };    @Nullable    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    public IBinder mBinder = new MyBinder();    public class MyBinder extends Binder {        public void feedBack() {            Log.d("AIDLService", "feedBack: is running");        }    }}

AndroidManifest.xml:

<service android:name=".AIDLService"            android:process=".remote"            android:exported="true">            <intent-filter>                <action android:name="com.bluetoothapp.aidl"/>                <category android:name="android.intent.category.DEFAULT"/>            </intent-filter>        </service>

假如熟习service的bind方式,就会觉得上面代码其实和写个普通service没啥区别。只是返回的对象就是AIDL中创立的对象。

6. 写用户端逻辑

在用户端bindService就可,就是普通的bindservice写法。

 if (serviceConnection == null) {            serviceConnection = new ServiceConnection() {                @Override                public void onServiceConnected(ComponentName name, IBinder service) {                    iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);                    Toast.makeText(SecondActivity.this, "onservice_connect", Toast.LENGTH_SHORT).show();                }                @Override                public void onServiceDisconnected(ComponentName name) {                }            };            Intent intent = new Intent();            intent.setAction("com.bluetoothapp.aidl");            intent.setClass(this, AIDLService.class);            bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);        }

编译可能会报错,如下

image.png

由于gradle构建的时候只会把src/main/java目录作为java代码目录,所以要加上

sourceSets {        main {            java.srcDirs = ['/src/main/java', 'src/main/aidl']        }    }

注意:bindService可能会发现报错,由于在android 5.0后强制要显式启动service 。
当前示例是在同个项目,在不同项目需要将aidl的目录拷贝一份
最后想说:写的比较通俗,主要是自我梳理和帮助没使用过的快速理解。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 快速掌握aidl

发表回复