美文网首页
AIDL实例

AIDL实例

作者: 糖葫芦_倩倩 | 来源:发表于2018-01-08 13:47 被阅读11次

说到进程间通信,一般首先就会想到AIDL,也看了很多文章,做下笔记,记录一下,方便以后查阅。

对于 AIDL 我是这样理解的,首先进程间是无法通信的,那要通信就得有一个媒介或者说两个进程有统一对外的接口可以相互识别,从这个 AIDL全程的名字Android Interface Definition Language (android 接口定义语言) 来看不难看出它就是我们进程间通信的媒介,它可以实现我们想要的通信。

在翻阅网上各类文章的讲解后,我认为一个比较好的实例可以更好理解这个东西,具体如下:

第一步

我们新创建两个module,代表我们两个进程,进程名称默认就是我们程序的包名:

image.png

第二步

我们先编写service这个module里的代码,先定义一个 Person的一个bean对象,记住一定要implements Parcelable 接口,大致如下:

image.png
public class Person implements Parcelable {
    private String mName;

    public Person(String name) {
        mName = name;
    }

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

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

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

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

    @Override
    public String toString() {
        return "\nPerson{" +
                "mName='" + mName + '\'' +
                '}';
    }

}

然后我们再新建一个文件夹:aidl,新建一个包名和Person类一模一样的包名和与之对应的aidl,还有一个我们对外提供获取person集合的一个aidl:

image.png
Person.aidl里,我们序列化我们java里的 Person 类:
package com.example.service.bean;

//还要和声明的实体类在一个包里,同时注意不要新建aidl文件,因为你会发现,新建不了,
//提示你名称唯一,此时你新建一个file,名字为Person.aidl就可以,需要特别注意下
parcelable Person;

IMyAidl.aidl 文件提供对外方法:

// IMyAidl.aidl
package com.example.service.bean;
//特别注意一定要手动导包,不会自动导包
import com.example.service.bean.Person;

// Declare any non-default types here with import statements
//可以理解为通信媒介
interface IMyAidl {

     /**
         * 除了基本数据类型,其他类型的参数都需要标上方向类型:in(输入), out(输出), inout(输入输出)
         */
        void addPerson(in Person person);

        List<Person> getPersonList();
}

然后在我们的java文件里,新建一个MyAidlService,

public class MyAidlService extends Service {

    private final String  TAG = this.getClass().getSimpleName();

    private ArrayList<Person> mPersons;

    /**
     * 创建生成本地的binder ,实现AIDL的方法
     */
    private IBinder mIBinder = new IMyAidl.Stub(){

        @Override
        public void addPerson(Person person) throws RemoteException {
            mPersons.add(person);
        }

        @Override
        public List<Person> getPersonList() throws RemoteException {
            return mPersons;
        }
    };

    /**
     * 客户端与服务端绑定时的回调,返回IBinder对象后客户端就可以通过它远程调用服务端的方法,即实现了通讯

     * @param intent
     * @return
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        mPersons = new ArrayList<>();
        return mIBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

最后别忘了在清单文件中注册MyAidlService

<service
            android:name="com.example.service.MyAidlService"
            android:enabled="true"
            android:exported="true" />

到此,我们完成了service端的工作:

第三步

将我们刚才创建好的aidl文件夹拷贝到 app modulemain文件夹下,在MainActivity中绑定服务,

Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.example.service","com.example.service.MyAidlService"));
        bindService(intent,mConnection,BIND_AUTO_CREATE);

其中这个mConnection可以让我们拿到IMyAidl对象的代理

private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

            mAidl = IMyAidl.Stub.asInterface(iBinder);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mAidl = null;
        }
    };

通过返回的IBinder 拿到这个IMyAidl,此时我们就可以通信了,例如我们调用IMyAidl中的addPerson方法,再调用getPersonList看看:

 Random random = new Random();
        Person person = new Person("qian"+random.nextInt(20));

        try{
            mAidl.addPerson(person);
            List<Person> mPersons = mAidl.getPersonList();

            tvName.setText(mPersons.toString());
        }catch (Exception e){
            e.printStackTrace();
        }

打印发现list 返回了我们添加的Person,完成了appservice两个进程间的通信。
demo地址:https://github.com/QQabby/AIDLDemo

相关文章

  • AIDL实例

    说到进程间通信,一般首先就会想到AIDL,也看了很多文章,做下笔记,记录一下,方便以后查阅。 对于 AIDL 我...

  • AIDL实例

    几句话:1.此实例实际上就是一个求和计算器;2.客户端是位于前台的Activity,用于数据的输入输出;3.服务器...

  • 每天五道Android面试题,轻松进大厂2018-12-21

    一、AIDL理解 此处延伸:简述Binder AIDL: 每一个进程都有自己的Dalvik VM实例,都有自己的一...

  • Android AIDL简单实例

    这篇文章就只是简单讲解以下AIDL的使用,如果需要详细的文档说明之类的请自行百度,Google【手动滑稽】 新建两...

  • IPC相关

    Android权限之sharedUserId、签名(实例说明) Android 中AIDL的使用与理解 Binde...

  • AIDL使用总结

    服务端进程: 1:创建AIDL文件如xxx.aidl 2:在接口中自定义方法,如果有bean则实例化改bean实体...

  • AIDL实例,双向通信

    服务端实现 接下来的过程演示了服务端怎么实现Android复杂的AIDL通信实例首先需要明白的一个事情,调用一个方...

  • 【Android实例】AIDL简单使用

    概述 什么是AIDL? Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通...

  • IPC(二)--AIDL使用实例

    移步Android跨进程通信IPC 使用流程 1.将想要进程间传递的对象序列化2.创建.aidl文件,并在文件内声...

  • Android Studio使用AIDL-实现进程间通讯

    参考: Android Studio创建AIDL文件并实现进程间通讯实例如何在AndroidStudio中使用AI...

网友评论

      本文标题:AIDL实例

      本文链接:https://www.haomeiwen.com/subject/onovnxtx.html