使用AIDL实现进程间通信

转载请注明出处,点击此处 查看更多精彩内容。

AIDL(Android Interface Definition Language) 是一种IDL语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。

以下的文件创建过程是基于Android Studio。

使用AIDL实现进程间通信步骤:

1. 创建.aidl文件

该文件结构类似与Java中的接口,定义了可用的方法和数据的接口。
右键点击程序包 --> new --> AIDL --> AIDL File 创建IMyAidlInterface.aidl文件,这时Android Studio会自动创建一个和java同级的目录aidl,并在此目录下生成包和.aidl文件。如图:
.aidl文件所在目录结构
现在定义一个求和的方法,修改后的IMyAidlInterface文件如下:

package ***.***.***;

interface IMyAidlInterface {

    int sum(int a, int b);

}

2. 生成.aidl文件对应的.java文件

通过 Build --> Rebuild Project 重新构建项目生成.aidl文件对应的.java文件,如图所示:
对应的.java文件所在目录结构

3. 创建共享Service

创建一个Service用于和其他进程共享数据和方法

    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;

    public class MyService extends Service {

        public MyService() {
        }

        @Override
        public IBinder onBind(Intent intent) {
           return mBinder;
        }

        IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {

            @Override
            public int sum(int a, int b) throws RemoteException {
                return a+b;
            }

        };

    }

Stub是生成IMyAidlInterface.java时自动生成的一个抽象内部类,继承自Binder。
由于在其他进程中并不能知道这个Service的名字,所以启动这个Service的时候需要使用隐式的Intent,因此需要给Service添加过滤器:

    <service
        android:name=".MyService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.mm.action.aidl" />
        </intent-filter>
    </service>

然后在启动Service的时候使用"com.mm.action.aidl"作为Action即可。

4. 启动共享Service

    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 获取定义的接口
            IMyAidlInterface aidlInterface = IMyAidlInterface.Stub.asInterface(service);
            try {
                // 调用接口中的方法
                System.out.println(aidlInterface.sum(100, 3));
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    // 使用bindService启动Service
    bindService(new Intent("com.mm.action.aidl"), connection, BIND_AUTO_CREATE);

有了以上的这些配置,就能先运行当前项目测试一下了,如果能正确打印数字的和,则以上配置就没有问题了。

5. 在其他项目中共享Service

新建一个项目,拷贝上面的.aidl文件到项目的同名目录下,然后Rebuild一下生成对应的.java文件,然后根据上面启动Service的方法启动即可。发布应用时,共享Service的APK要使用同一个签名,否则无法正常共享。

6. 传递复杂对象

6.1

使用AIDL可以直接传递基本数据类型(int long float double)、String、List和Map,如果要传递复杂对象,需要使该对象实现Parcelable接口,并创建同名的.aidl文件。
现在我们创建Person.aidl和Person.java
Person.aidl:

package ***;

parcelable Person;

Person.java :

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

    /**
     * Created by shichaohui on 15/11/4.
     */
    public class Person implements Parcelable {

        String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(this.name);
        }

        public Person() {
        }

        protected Person(Parcel in) {
            this.name = in.readString();
        }

        public static final Creator<Person> CREATOR = new Creator<Person>() {
            public Person createFromParcel(Parcel source) {
                return new Person(source);
            }
    
            public Person[] newArray(int size) {
                return new Person[size];
            }
        };
    }
6.2

修改IMyAidlInterface.aidl,添加一个获取Person的方法,修改后的IMyAidlInterface.aidl文件:

    import com.***.androidtest.Person;

    interface IMyAidlInterface {

        int sum(int a, int b);

        Person getPerson();
    }

这里一定要记得import Person.java所在的包,不然会构建失败。

6.3

修改MyService,实现getPerson()方法:

    public class MyService extends Service {

        ...

        IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {

           ...

            @Override
            public Person getPerson() throws RemoteException {
                Person person = new Person();
                person.setName("nammmmme");
                return person;
            }

        };

    }

最后就可以和使用sum()方法一样使用getPerson()方法了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
AIDL(Android Interface Definition Language)是一种用于 Android 平台的接口定义语言,它可以帮助不同进程的组件进行通信。下面是使用 AIDL 进行进程通信的步骤: 1.定义 AIDL 接口 首先,在服务端和客户端之定义一个 AIDL 接口。在 AIDL 文件中,定义需要向客户端公开的方法和参数。 2.实现 AIDL 接口 在服务端中,实现定义的 AIDL 接口,并在 onCreate() 方法中将其注册到系统中。 3.绑定服务端 在客户端中,使用 bindService() 方法绑定服务端。 4.获取 AIDL 接口实例 在客户端中,实现 ServiceConnection 接口,当服务端连接成功时,会回调 onServiceConnected() 方法。在此方法中,可以获取到 AIDL 接口实例。 5.调用 AIDL 接口方法 在客户端中,通过获取到的 AIDL 接口实例,即可调用服务端暴露的方法。 下面是一个简单的示例代码: 服务端: ``` //定义 AIDL 接口 interface IMyAidlInterface { int add(int a, int b); } //实现 AIDL 接口 class MyAidlInterfaceImpl extends IMyAidlInterface.Stub { @Override public int add(int a, int b) throws RemoteException { return a + b; } } //在 onCreate() 方法中注册 AIDL 接口 @Override public void onCreate() { super.onCreate(); Intent intent = new Intent(this, MyAidlInterfaceService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); Log.i(TAG, "MyAidlInterfaceService is created."); } //定义 ServiceConnection 对象,以便在客户端连接时获取 AIDL 接口实例 private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); Log.i(TAG, "MyAidlInterfaceService is connected."); } @Override public void onServiceDisconnected(ComponentName name) { mIMyAidlInterface = null; Log.i(TAG, "MyAidlInterfaceService is disconnected."); } }; ``` 客户端: ``` //定义 ServiceConnection 对象 private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //获取 AIDL 接口实例 mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); Log.i(TAG, "MyAidlInterfaceService is connected."); } @Override public void onServiceDisconnected(ComponentName name) { mIMyAidlInterface = null; Log.i(TAG, "MyAidlInterfaceService is disconnected."); } }; //使用 bindService() 方法绑定服务端 Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.myaidlservice", "com.example.myaidlservice.MyAidlInterfaceService")); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); //调用服务端暴露的方法 int result = mIMyAidlInterface.add(1, 2); ``` 希望这个简单的示例可以帮助你了解如何使用 AIDL 进行进程通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值