AIDL进行进程间通讯

AIDL进行进程间通讯

AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言

在上一篇 使用Messenger进行跨应用(进程)通讯中,使用Messenger进行进程间通讯的时候,服务端是能一个个的处理客户端的请求,如果有大量的并发请求的时候,Messenger就不适用了.并且Messenegr只能传递消息,并不能跨进程调用服务端的方法,这时候可以使用AIDL来实现跨进程调用服务端的方法.

AIDL持的数据类型包括:

  • java的8种基本数据类型byte,short,int,long,float,double,boolean,char

  • String和CharSequence

  • List:只支持ArrayList.List种的元素必须是AIDL支持的数据类型

  • Map:只支持HashMap,.Map的元素必须是AIDL支持的数据类型

  • Parcelable:实现了Parcelable接口的 对象

  • AIDL:所有的AIDL接口本身也可以在AIDL文件中使用.

    当AIDL使用类型是Parcelable时必须导包,即使Parcelable和AIDL在同一包内.另外在AIDL中,除了基本数据类型,其他类型的参数必须加上定向TAG,in out或者inout,in表示输入型参数,out表示输出型参数,inout表示输入输出型参数,我们要根剧实际情况来使用TAG,不能忙盲目的使用inout,因为在底层是有开销的.

​ 为了开发方便,建议把所有跟AIDL有关的文件都放在同一包内,当客户端和服务端是两个不同的应用时,需要把AIDL的相关的文件全部复制到客服端内.放在一个包内不容易出错.

服务端的实现

​ 要实现的简单的功能,服务端有两个方法,可以向List 中addPerson,也可以获取List中获取全部的Person

  • 编写AIDL文件

    使用Android Studio编写AIDL文件
    在这里插入图片描述

然后会在Android Studio会在src/main下 会自动创建一个aidl文件夹.然后把所有跟AIDL有关的文件都创建在这个包下.

在这里插入图片描述

  1. 因为Person类不是AIDL支持的基本数据类型,所以要实现Parcelable接口

    public class Person implements Parcelable {
        private String name;
    
        public Person(Parcel in) {
            name = 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];
            }
        };
    
        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(name);
        }
    }
    
  2. 因为Person类实现了Parcelable,所以要创建一个Person.aidl

    // Book.aidl
    package com.lixxy.service;
    
    // Declare any non-default types here with import statements
    parcelable Person;
    
  3. 最后编写IPersonAidl.aidl.因为服务端有两个方法,所以IPersonAidl.aidl也要定义相同方法

    // IBookAidl.aidl
    package com.lixxy.service;
    import com.lixxy.service.Person;
    
    interface IPersonAidl {
    
       List<Person> getList();
       void addPerson(in Person person);
    }
    

编写完ADIL以后还需要在bulid.gradle android{}中加入

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

因为Android Studio自动生成的AIDL文件夹与java文件夹包名一致,为了使编译器能找到Person类,所以要加上,不然会报错

AIDL相关的文件编写完成后需要Make Project,Android Studio会自动为我们生成IPersonAidl.java 接口

  • 编写PersonService
public class PersonManagerService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Person person = new Person();
        person.setName("小红");
        mPeople.add(person);
    }

    public static final String TAG = "=========>";

    //包含Person对象的list
    private List<Person> mPeople = new ArrayList<>();


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "绑定成功");

        return mBinder;
    }

    private Binder mBinder = new IPersonAidl.Stub() {

        @Override
        public List<Person> getList() throws RemoteException {
            return mPeople;
        }

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

然后需要在AndroidManifest中声名PersonManagerService

  <service
      android:name=".PersonManagerService"
       android:exported="true">
 </service>
客户端的实现

首先先创建AIDL文件夹,然后在AIDL文件夹下创建于服务端相同的包,然后把服务端AIDL文件夹下所有的问价都复制过来
在这里插入图片描述

然后Make Project,自动生成文件.
最后编写Activity

package com.lixxy.aidldemo;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


import com.lixxy.service.Person;
import com.lixxy.service.IPersonAidl;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "===>";
    private IPersonAidl mIBookAidl;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        final Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.lixxy.service", "com.lixxy.service.PersonManagerService"));

        Button button = findViewById(R.id.mBtnBind);
        Button get = findViewById(R.id.mBtnGet);
        Button add = findViewById(R.id.mBtnAdd);
        final TextView name = findViewById(R.id.mTvName);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
            }
        });

        get.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    List<Person> list = mIBookAidl.getList();
                    StringBuilder builder = new StringBuilder();
                    for (Person person : list) {
                        builder.append(person.getName());
                    }
                    name.setText(builder.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }


            }
        });

        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Person person = new Person();
                person.setName("小明");
                try {
                    mIBookAidl.addPerson(person);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });


    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mIBookAidl = IPersonAidl.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG,"连接失败");
        }
    };
}

最后附上项目地址:https://github.com/Lillls/AidlDemo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值