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添加一個信息(添加的是一個空對象),然後再獲取全部


代碼比較簡單,我就不上傳了,有意見請跟帖!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章