Kotlin-Android开发之AIDL的使用介绍

前言: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添加一个信息(添加的是一个空对象),然后再获取全部


代码比较简单,我就不上传了,有意见请跟帖!

发布了117 篇原创文章 · 获赞 80 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_32306361/article/details/104061948