前言:AIDL的英文全称是Android Interface Definition Language,翻译成中文是安卓接口定义语言。用来定义服务器和客户端通信接口的一种描述语言。含义比较晦涩难懂,简单的理解就是一个APP要访问另一个APP的数据,这就需要用到AIDL了。
1.AIDL介绍:全称是Android Interface Definition Language,简单的理解就是一个APP要访问另一个APP的数据,这就需要用到AIDL了。
2.支持以下几种类型
- 八种基本数据类型:byte、char、short、int、long、float、double、boolean
- String,CharSequence
- 实现了Parcelable接口
- List 类型和Map类型
3. 主要分为2类
- 用来声明实现了Parcelable接口的数据类型
- 用来定义接口方法,声明要暴露哪些接口给客户端调用
4.定向TAG
- in 表示数据只能由客户端流向服务端
- out 表示数据只能由服务端流向客户端
- inout 表示数据可在服务端与客户端之间双向流通
接下来看具体Demo(注意:使用Kotlin编程语言)
(一)服务器端
1.新建一个module作为service,然后选中main文件夹右键选择新建一个aidl的文件夹
2.选中aidl文件夹,右键选择新建两个aidl文件,然后会自动生成路径。‘
此时MyAidl.aidl里面的接口方法可为空
StudentBean.aidl代码为
package com.fly.service;
parcelable StudentBean;
3.Build一下,生成debug文件,然后建立起对应的StudentBean.kt继承Parcelable类
4.新建一个StudentBean.kt (注意:如果没有实现第三步,则下面的方法中则会报错)
package com.fly.service
import android.os.Parcel
import android.os.Parcelable
class StudentBean() : Parcelable {
private var name: String = ""
private var grade: Int = 0
constructor(name: String, grade: Int) : this() {
this.name = name
this.grade = grade
}
constructor(parcel: Parcel) : this() {
name = parcel.readString().toString()
grade = parcel.readInt()
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeInt(grade)
}
override fun describeContents(): Int {
return 0
}
fun readFromParcel(reply: Parcel) {
name = reply.readString().toString()
grade = reply.readInt()
}
companion object CREATOR : Parcelable.Creator<StudentBean> {
override fun createFromParcel(parcel: Parcel): StudentBean {
return StudentBean(parcel)
}
override fun newArray(size: Int): Array<StudentBean?> {
return arrayOfNulls(size)
}
}
}
5.MyAidl.aidl代码补充完整,首先导入StudentBean所在的包和名字,然后创建接口方法
package com.fly.service;
import com.fly.service.StudentBean;
interface MyAidl {
List<StudentBean> getStudentBeanList();
void addStudentBeanInOut(inout StudentBean bean);
void addStudentBeanIn(in StudentBean bean);
void addStudentBeanOut(out StudentBean bean);
}
6.然后重复第3步,Build一下。
7.新建一个MyAidlService.kt继承Service,然后利用Ibinder调用MyAidl的方法
package com.fly.service
import android.app.Service
import android.content.Intent
import android.os.IBinder
import java.util.ArrayList
class MyAidlService : Service() {
private lateinit var studentArrayList: ArrayList<StudentBean>
override fun onCreate() {
super.onCreate()
studentArrayList = ArrayList()
initData()
}
private fun initData() {
var studentBean1 = StudentBean("fly1",21)
var studentBean2 = StudentBean("fly2",22)
var studentBean3 = StudentBean("fly3",23)
var studentBean4 = StudentBean("fly4",24)
studentArrayList.add(studentBean1)
studentArrayList.add(studentBean2)
studentArrayList.add(studentBean3)
studentArrayList.add(studentBean4)
}
override fun onBind(intent: Intent?): IBinder? {
return iBinder
}
private val iBinder = object : MyAidl.Stub() {
override fun getStudentBeanList(): MutableList<StudentBean> {
return studentArrayList
}
override fun addStudentBeanInOut(bean: StudentBean?) {
if (bean != null) {
studentArrayList.add(bean)
}
}
override fun addStudentBeanIn(bean: StudentBean?) {
if (bean != null) {
studentArrayList.add(bean)
}
}
override fun addStudentBeanOut(bean: StudentBean?) {
if (bean != null) {
studentArrayList.add(bean)
}
}
}
}
8.在MainActivity中开启这个服务
package com.fly.service
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startService(Intent(this,MyAidlService::class.java))
}
override fun onDestroy() {
super.onDestroy()
stopService(Intent(this,MyAidlService::class.java))
}
}
9.在清单文件中注册这个服务
<service android:name=".MyAidlService" android:exported="true"/>
10.看一下包的结构,看一下和我的是否一样
(二)客户端的代码实现
1.新建一个module的client(客户端),然后把service下的aidl文件夹直接粘贴复制到client下(注意包的名字)
2.把StudentBean.kt以及所在的包的名字粘贴复制过来(注意包的名字还是com.fly.service)
3.在MainActivity中绑定服务,然后调用MyAidl的方法。
package com.fly.client
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.fly.service.MyAidl
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.content.ServiceConnection
import android.util.Log
import android.view.View
import com.fly.service.StudentBean
class MainActivity : AppCompatActivity() {
private lateinit var myAidl: MyAidl
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
bindService()
}
private fun bindService() {
val intent = Intent()
intent.component = ComponentName(
"com.fly.service",
"com.fly.service.MyAidlService"
)
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
}
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
myAidl = MyAidl.Stub.asInterface(service)
}
override fun onServiceDisconnected(name: ComponentName) {
}
}
fun click1(view: View) {
var list:List<StudentBean> = myAidl.studentBeanList
for (bean in list){
Log.e("-name--",bean.name)
Log.e("-grade--",bean.grade.toString())
}
}
fun click2(view: View) {
myAidl.addStudentBeanInOut(StudentBean("www",99))
}
fun click3(view: View) {
myAidl.addStudentBeanIn(StudentBean("xyz",100))
}
fun click4(view: View) {
myAidl.addStudentBeanOut(StudentBean("xxx",101))
}
}
对应的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:onClick="click1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="获取所有数据"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:onClick="click2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="利用InOut添加"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:onClick="click3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="利用In添加"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:onClick="click4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="利用out添加(添加失败)"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
(三)分别运行servic和client
1.切换到client页面,点击第一个按钮
2.点击第二个按钮,利用InOut添加一个信息,然后再获取全部信息
3.点击第三个按钮,利用In添加一个信息,然后再获取全部
4.点击第四个按钮,利用out添加一个信息(添加的是一个空对象),然后再获取全部
代码比较简单,我就不上传了,有意见请跟帖!