Android AIDL案例实践

AIDL :Android Interface Define Language(Android接口定义语言)

主要用于多应用进程间通信

通过Android来进行数据通信

默认支持的数据类型:

1、基本数据类型(int ,long, boolean, double, float, byte char ) <不支持short>

2、String,CharSequence

3、List,Map

4、Parcelable

案例–简单传值:

​ 客户端与服务端通讯,处理后返回客户端数据

​ 实现原理:

​ 1、需要一个ServiceAPP、一个ClientAPP;

​ 2、两个app都需要创建aidl,两个APP中相同的文件位置、相同包名下的.aidl文件

扫描二维码关注公众号,回复: 2692607 查看本文章

​ 3、ServiceAPP中需要创建一个Service

​ 4、ClientAPP中需要绑定服务,并获取连接返回参数

ServiceApp:

1、AidlService.java

2、mian->aidl->包名->IMyAidlInterface.aidl

源代码:

//记得注册Service
public class AidlService extends Service {
    public AidlService() {
    }

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

    private IBinder iBinder = new IMyAidlInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public int add(int num1, int num2) throws RemoteException {
            Log.e("chenxh","收到遠程數據"+num1+" "+num2);
            return num1+num2+num2;
        }
    };

}
interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    int add(int num1,int num2);

}

ClientAPP:

1、需要将ServiceAPP下的aidl整个复制到同样目录下

2、需要在MainActivity做一些处理,绑定服务,并开启服务回调

源代码:

class MainActivity : AppCompatActivity() {
    private var myAidl: IMyAidlInterface? = null
    private var intentService: Intent? = null


    private val conn = object : ServiceConnection {

        //绑定服务,回调onBind()方法
        @SuppressLint("WrongConstant")
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            myAidl = IMyAidlInterface.Stub.asInterface(service)
            Toast.makeText(this@MainActivity, myAidl!!.add(4, 5).toString(), Toast.LENGTH_LONG).show()

        }

        override fun onServiceDisconnected(name: ComponentName) {
            myAidl = null
        }

    }


    @SuppressLint("WrongConstant")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initViewControl()
        intentService = Intent()
        intentService!!.setComponent(ComponentName("com.wfj.chinaums.umsaidldemo", "com.wfj.chinaums.umsaidldemo.AidlService"))
        bindService(intentService, conn, Context.BIND_AUTO_CREATE)
    }

    override fun onDestroy() {
        super.onDestroy()
        unbindService(conn)
    }

    @SuppressLint("WrongConstant")
    fun initViewControl() {

        send_AIDL_btn.setOnClickListener {
            var res: Int = myAidl!!.add(2, 3)
            show_text.setText(res.toString())
        }
    }

}

案例–传对象:

报错:

aidl 在服务端的报错,网上有说编译工具的报错,其实是Person.java实体类的原因,放在包名下就好是,但是放在包名下的entity的实体类包下就报如下错误,

Error:Execution failed for task ':app:compileDebugAidl'.
> java.io.IOException: com.android.ide.common.process.ProcessException: Error while executing process D:\Android\chenxh\AppData\Local\Android\sdk\build-tools\28.0.1\aidl.exe with arguments {-pD:\Android\chenxh\AppData\Local\Android\sdk\platforms\android-26\framework.aidl -oH:\AndroidTestDemo\UMSAIDLDemo\app\build\generated\source\aidl\debug -IH:\AndroidTestDemo\UMSAIDLDemo\app\src\main\aidl -IH:\AndroidTestDemo\UMSAIDLDemo\app\src\debug\aidl -IC:\Users\chenxh\.gradle\caches\transforms-1\files-1.1\support-media-compat-25.3.1.aar\a52317ec2e0d19bd336c8772a4dc550f\aidl -IC:\Users\chenxh\.gradle\caches\transforms-1\files-1.1\support-compat-25.3.1.aar\f457844d024605d217e73cc2d7540a92\aidl -dC:\Users\chenxh\AppData\Local\Temp\aidl7433044909415441156.d H:\AndroidTestDemo\UMSAIDLDemo\app\src\main\aidl\com\wfj\chinaums\umsaidldemo\IAIDLPerson.aidl}

项目结构:

AIDL传对象项目结构

一、第一步在APPService服务端开发:

1、首先传递的对象一定要序列化,对象要实现Parcelable

public class Person implements Parcelable{

    private String name;
    private String sex;
    private int age;

    public Person() {
    }

    public Person(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    protected Person(Parcel in) {
        name = in.readString();
        sex = in.readString();
        age = in.readInt();
    }

    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 parcel, int i) {
        parcel.writeString(name);
        parcel.writeString(sex);
        parcel.writeInt(age);
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

2、在main下创建aidl文件,需要创建Person.aidl、IAIDLPerson.aidl,记得build

Person.aidl源码

*注意person实体类的导包,parcelable的声明

// Person.aidl
package com.wfj.chinaums.umsaidldemo;
import com.wfj.chinaums.umsaidldemo.Person;
// Declare any non-default types here with import statements

parcelable Person;

IAIDLPerson.aidl源码

*这里需要注意person的导包;传递对象参数的in out inout字段

  • in 表示数据只能由客户端流向服务端,
  • out 表示数据只能由服务端流向客户端,
  • inout 则表示数据可在服务端与客户端之间双向流通
// IAIDLPerson.aidl
package com.wfj.chinaums.umsaidldemo;
import com.wfj.chinaums.umsaidldemo.Person;
// Declare any non-default types here with import statements

interface IAIDLPerson {
 /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    List<Person> addInPerson(in Person person);

}

3、AidlService.java 创建服务,让客户端绑定进行回传处理

package com.wfj.chinaums.umsaidldemo;

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

import java.util.ArrayList;
import java.util.List;

public class AidlService extends Service {
    public AidlService() {
    }

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

    private IBinder mBinder = new IAIDLPerson.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public List<Person> addInPerson(Person person) throws RemoteException {
            List<Person> personList = new ArrayList<>();
            personList.add(person);
            return personList;
        }
    };

}

二、在APPClient客户端开发:

1、需要在同样包名下创建相同的实体类Person.java

package com.wfj.chinaums.umsaidldemo;

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

/**
 * Created by chenxh on 2018/8/8.
 *
 */

public class Person implements Parcelable{

    private String name;
    private String sex;
    private int age;

    public Person() {
    }

    public Person(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    protected Person(Parcel in) {
        name = in.readString();
        sex = in.readString();
        age = in.readInt();
    }

    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 parcel, int i) {
        parcel.writeString(name);
        parcel.writeString(sex);
        parcel.writeInt(age);
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

2、创建AIDL文件,需要复制Server的aidl下的所有文件,同样需要完全一致

3、在MainAcitivity.kt下绑定服务,调用AIDL

class MainActivity : AppCompatActivity() {
    private var myAidl: IAIDLPerson? = null
    private var intentService: Intent? = null

    private var mlist:MutableList<Person>? = mutableListOf()


    private val conn = object : ServiceConnection {

        //绑定服务,回调onBind()方法
        @SuppressLint("WrongConstant")
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            myAidl = IAIDLPerson.Stub.asInterface(service)
        }

        override fun onServiceDisconnected(name: ComponentName) {
            myAidl = null
        }

    }


    @SuppressLint("WrongConstant")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initViewControl()
        intentService = Intent()
        intentService!!.setComponent(ComponentName("com.wfj.chinaums.umsaidldemo", "com.wfj.chinaums.umsaidldemo.AidlService"))
        bindService(intentService, conn, Context.BIND_AUTO_CREATE)
    }

    override fun onDestroy() {
        super.onDestroy()
        unbindService(conn)
    }

    @SuppressLint("WrongConstant")
    fun initViewControl() {

        send_AIDL_btn.setOnClickListener {
            mlist!!.addAll(myAidl!!.addInPerson(Person("chenxh","sex",123)))
            mlist!!.forEach { Log.e("chenxh",it.toString()) }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Mr_ChenXu/article/details/81542915