Android studio中创建aidl文件

本文详细介绍使用AIDL(Android Interface Definition Language)实现Android应用间的跨进程通信过程。包括定义可传递对象Book类,创建AIDL接口文件Book.aidl及IBookManager.aidl,自动生成IBookManager.java文件等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新建aidl文件夹:

在新建里的aidl文件夹中新建Java文件:其中Book实现了parcelable接口


Book代码:

package cqupt.second.aidl;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {

    public int bookId;
    public String bookName;

    public Book() {

    }

    public Book(int bookId, String bookName) {
        this.bookId = bookId;
        this.bookName = bookName;
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(bookId);
        out.writeString(bookName);
    }

    public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    private Book(Parcel in) {
        bookId = in.readInt();
        bookName = in.readString();
    }

    @Override
    public String toString() {
        return String.format("[bookId:%s, bookName:%s]", bookId, bookName);
    }
}

创建aidl文件、创建Book.aidl、创建IBookManager.aidl:



Book.aidl中的代码:

package cqupt.second.aidl;

parcelable Book;

IBookManager.aidl中的代码:

package cqupt.second.aidl;
import cqupt.second.aidl.Book;
interface IBookManager {
    List<Book> getBookList();
    void addBook(in Book book);
}
最终自动生成了IBookManager.java文件:



IBookManager.java中的代码:

package cqupt.second.aidl;

public interface IBookManager extends android.os.IInterface {
    public java.util.List<cqupt.second.aidl.Book> getBookList()
        throws android.os.RemoteException;

    public void addBook(cqupt.second.aidl.Book book)
        throws android.os.RemoteException;

    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements cqupt.second.aidl.IBookManager {
        private static final java.lang.String DESCRIPTOR = "cqupt.second.aidl.IBookManager";
        static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION +
            0);
        static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION +
            1);

        /** Construct the stub at attach it to the interface. */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an cqupt.second.aidl.IBookManager interface,
         * generating a proxy if needed.
         */
        public static cqupt.second.aidl.IBookManager asInterface(
            android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }

            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

            if (((iin != null) &&
                    (iin instanceof cqupt.second.aidl.IBookManager))) {
                return ((cqupt.second.aidl.IBookManager) iin);
            }

            return new cqupt.second.aidl.IBookManager.Stub.Proxy(obj);
        }

        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        @Override
        public boolean onTransact(int code, android.os.Parcel data,
            android.os.Parcel reply, int flags)
            throws android.os.RemoteException {
            switch (code) {
            case INTERFACE_TRANSACTION: {
                reply.writeString(DESCRIPTOR);

                return true;
            }

            case TRANSACTION_getBookList: {
                data.enforceInterface(DESCRIPTOR);

                java.util.List<cqupt.second.aidl.Book> _result = this.getBookList();
                reply.writeNoException();
                reply.writeTypedList(_result);

                return true;
            }

            case TRANSACTION_addBook: {
                data.enforceInterface(DESCRIPTOR);

                cqupt.second.aidl.Book _arg0;

                if ((0 != data.readInt())) {
                    _arg0 = cqupt.second.aidl.Book.CREATOR.createFromParcel(data);
                } else {
                    _arg0 = null;
                }

                this.addBook(_arg0);
                reply.writeNoException();

                return true;
            }
            }

            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements cqupt.second.aidl.IBookManager {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            @Override
            public java.util.List<cqupt.second.aidl.Book> getBookList()
                throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                java.util.List<cqupt.second.aidl.Book> _result;

                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_getBookList, _data,
                        _reply, 0);
                    _reply.readException();
                    _result = _reply.createTypedArrayList(cqupt.second.aidl.Book.CREATOR);
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }

                return _result;
            }

            @Override
            public void addBook(cqupt.second.aidl.Book book)
                throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();

                try {
                    _data.writeInterfaceToken(DESCRIPTOR);

                    if ((book != null)) {
                        _data.writeInt(1);
                        book.writeToParcel(_data, 0);
                    } else {
                        _data.writeInt(0);
                    }

                    mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
        }
    }
}
其中:DESCRIPTOR是Binder的唯一标识,一般用当前Binder类名表示

    asInterface(android.os.IBinder obj):用于将服务端的Binder对象转换成客户端所需要的AILDL接口类型的对象,如果客户端与服务端在同一进程,返回服务端的Stub对象本身,否则返回系统封装后的Stub.proxy对象

    asBinder():返回当前Binder对象

    onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags):运行在服务端的Binder线程池中,当客户端发起进程间请求,远程请求会通过系统封装之后交由此方法处理。服务端通过code可以确定客户端请求的目标方法是什么,接着从data中取出目标方法所需要的参数(如果目标方法有参数的话),然后执行目标方法。放执行完毕之后,向reply中写入返回值(如果有返回值的话)

    Proxy类中的getBookList():客户端调用获取数据。将创建该方法所需要的参数:输入型Parcel对象_data、输出型Parcel对象_reply和返回值队形List写入该方法的参数_data中,然后调用transact方法发起RPC(远程过程调用)请求,同时线程被挂起,接着服务端调用onTransact()方法,RPC过程结束,当前线程继续执行,从_reply中取出RPC过程返回的数据,最后返回_reply中的数据

    Proxy类中的addBook(cqupt.second.aidl.Book book):客户端调用,过程与getBookList()类似


注意:客户端发起请求后,当前线程会被挂起,直到服务端进程返回数据。

    服务端的Binder方法运行在Binder线程池中。



给Binder设置死亡代理:

private IBookManager mRemoteBookManager;
    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            if (mRemoteBookManager == null) {
                return;
            }
            mRemoteBookManager.asBinder().unlinkToDeath(mDeathRecipient, 0);
            mRemoteBookManager = null;
            // TODO: 2017/2/12 重新绑定service

        }
    };

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            IBookManager bookManager = IBookManager.Stub.asInterface(service);
            mRemoteBookManager = bookManager;
            try {
                mRemoteBookManager.asBinder().linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };



### 如何在 Android Studio 中成功创建 AIDL 文件 为了确保能够在 Android Studio 中成功创建并使用 AIDL 文件,以下是详细的说明以及可能的错误原因分析。 #### 1. 正确配置项目结构 要在 Android Studio 中生成 Java 文件,需按照以下方法设置项目的文件夹结构: - 在 `main` 目录下新建一个名为 `aidl` 的文件夹[^2]。 - 在此文件夹中创建一个新的包(即子文件夹),其名称应与 `AndroidManifest.xml` 文件中的 `package` 属性一致。如果导入的是已存在的 AIDL 文件,则包名应当匹配该 AIDL 文件定义的包名。 #### 2. 自动生成 Java 文件的位置 完成上述操作后,在构建过程中会自动生成对应的 Java 文件。这些文件通常位于路径 `build/generated/source/aidl/debug` 下。如果没有发现生成的文件,请检查 Gradle 配置是否正确加载了 AIDL 支持功能。 #### 3. 检查 AIDL 文件语法 某些情况下,AIDL 文件本身可能存在语法问题或其他不兼容的情况,这可能导致无法正常生成 Java 文件。例如,带有中文注释的 AIDL 文件可能会引发此类问题[^5]。建议移除所有非 ASCII 字符或将其替换为英文注释来解决问题。 #### 4. 客户端 Manifest 文件调整 对于涉及跨应用调用的服务场景,还需要注意客户端应用程序的 `AndroidManifest.xml` 是否进行了适当声明。具体来说,可以尝试通过 `<queries>` 节点指定目标服务的相关信息以便于解析和服务连接建立过程顺利进行[^4]。 #### 可能的错误及其解决办法 - **未找到生成的 Java 文件** - 确认 `aidl` 文件夹已被正确定义,并且其中包含了有效的 AIDL 文件。 - 清理并重新构建项目 (`Build -> Clean Project`, `Build -> Rebuild Project`) 来触发新的编译流程[^3]。 - **生成的 Java 文件为空白** - 如果存在带中文字符或者其他特殊编码格式的内容作为注解部分,考虑清理掉这些问题字段或将它们转换成标准英语表述形式。 ```python // 示例代码片段展示如何简单验证 aidl 功能 import android.os.IBinder; public interface IMyService extends IBinder { void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值