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文件
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.xx.xx.umsaidldemo", "com.xx.xx.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\xx\xx\umsaidldemo\IAIDLPerson.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.xx.xx.umsaidldemo;
import com.xx.xx.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.xx.xx.umsaidldemo;
import com.xx.xx.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.xx.xx.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.xx.xx.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.xx.xx.umsaidldemo", "com.xx.xx.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()) }
}
}
}