ADIL簡單測試實例

參考資料:https://blog.csdn.net/geyichongchujianghu/article/details/130045373
這個連接是Java的代碼,我根據它的鏈接寫了一個kotlin版本的。

AIDL(Android Interface Definition Language)是Android平臺上用于進程間通信(IPC)的一種接口定義語言。它允許不同進程中的組件(如服務和服務、服務和活動等)相互通信。

AIDL的主要特點包括:

  1. 跨進程通信:AIDL允許不同進程中的組件相互通信,這使得應用可以更好地利用設備的多核處理器,提高性能和響應速度。
  2. 接口定義:通過AIDL,開發者可以定義一個接口,并在這個接口中聲明需要跨進程傳遞的方法和數據類型。
  3. 自動生成代碼:Android SDK提供了一個編譯器,它可以根據AIDL接口定義自動生成Java代碼,這些代碼負責處理跨進程通信的細節。
  4. 支持多種數據類型:AIDL支持基本數據類型、字符串、列表、映射等多種數據類型,以及自定義的Parcelable對象。
  5. 安全性:AIDL通信是通過Binder機制實現的,Binder機制提供了進程間通信的安全性,確保只有授權的進程可以訪問服務。

使用AIDL的步驟通常包括:

  • 定義AIDL接口(.aidl文件)。
  • 實現AIDL接口的服務端。
  • 在客戶端使用AIDL接口與服務端通信。

AIDL是Android平臺上實現跨進程通信的重要工具,它為開發者提供了一種方便、高效的方式來實現不同進程間的數據交換和方法調用。

下面介紹了AIDL的使用例子,創建了兩個App,一個是服務端的mainapp,一個是客戶端的otherapp,它們會被創建在一個工程里,這樣也會方便調試。

一、創建兩個App

新建一個mainapp,我新建了一個aidlTest,創建了一個mainapp,這個aidlTest文件夾并沒有什么用。
image.jpg
把MainActivity重命名成MainAppActivity
image.jpg
再添加一個otherapp的module
image.jpg
模塊名字為otherapp
image.jpg

二、在mainapp里創建一個service

先在mainapp中實現一個service,MainAppActivity類中創建了service
image.jpg
service名字為MainAppService
image.jpg
修改MainAppAcitvity里的代碼

class MainAppActivity : AppCompatActivity() {private val TAG = "AIDL-MainAppActivity"override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)enableEdgeToEdge()setContentView(R.layout.activity_main)ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)insets}Log.v(TAG, "onCreate()")}override fun onDestroy() {super.onDestroy()Log.v(TAG, "onDestroy()")}
}

MainAppService里的改動,我們又重寫了onCreate()、onStartCommand()和onDestroy()這3個方
法,它們是每個Service中最常用到的3個方法了。其中:

  • onCreate()方法會在Service創建的時候調用
  • onStartCommand()方法會在每次Service啟動的時候調用,
  • onDestroy()方法會在Service銷毀的時候調用。
  • onBind是被客戶端綁定時執行
  • onUnbind(Intent intent):被客戶端解綁時執行
class MainAppService : Service() {private val TAG = "AIDL-MainAppService"override fun onCreate() {super.onCreate()}override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {return super.onStartCommand(intent, flags, startId)}override fun onBind(intent: Intent): IBinder {TODO("Return the communication channel to the service.")}override fun onUnbind(intent: Intent?): Boolean {Log.v(TAG, "onUnbind()")return super.onUnbind(intent)}override fun onDestroy() {super.onDestroy()Log.v(TAG, "onDestroy()")}
}

三、mainapp里實現AIDL

在創建aidl前,需要在mainapp的gradle里,配置打開aidl

buildFeatures {aidl = true
}

在mainapp的main目錄下創建一個名為IAppAidlInterface.aidl的文件
image.jpg

image.jpg
在IAppAidlInterface里添加setStringData這個AIDL接口定義了一個名為IAppAidlInterface的接口,它包含了兩個方法:basicTypessetStringData

  • basicTypes方法展示了在AIDL接口中可以使用的一些基本數據類型作為參數。這些基本數據類型包括整型(int)、長整型(long)、布爾型(boolean)、浮點型(float)、雙精度浮點型(double)和字符串型(String)。這個方法沒有返回值,它的目的是演示如何在AIDL接口中使用這些基本數據類型。
  • setStringData方法接受一個字符串參數(String strData),并將其設置為某個值。這個方法也沒有返回值,它的目的是演示如何在AIDL接口中傳遞字符串數據。

這個AIDL接口定義了兩個沒有返回值的方法,它們可以用于跨進程通信。在實際應用中,你可以根據需要定義更多的方法和參數,以實現不同進程間的數據交換和方法調用。

interface IAppAidlInterface {/*** 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);void setStringData(String strData);
}

在AIDL創建完成后,點擊重新編譯后就有生成的java類了。在Android中,當你定義了一個AIDL(Android Interface Definition Language)接口后,Android的編譯器會自動為你生成一個Java接口類。這個生成的接口類繼承自android.os.IInterface,并包含了你在AIDL文件中定義的方法。
image.jpg

四.otherapp中也實現AIDL

把mainapp里的aidl文件復制到otherapp里,并開啟aidl后,就也能看到生成的aidl java文件
image.jpg

五、在mainapp中添加代碼

現在MainAppService中實例化Binder

package com.example.mainappimport android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Logclass MainAppService : Service() {private val TAG = "AIDL-MainAppService"private val mStub = AppAidlInterfaceStub()/* * 實現IAppAidlInterface.Stub抽象類,* 用于實現IAppAidlInterface.aidl中的接口函數* onBinder()時返回匿名內部類實例*/inner class AppAidlInterfaceStub : IAppAidlInterface.Stub() {var mStrData = ""var mSetServiceRunning = trueoverride fun basicTypes(anInt: Int,aLong: Long,aBoolean: Boolean,aFloat: Float,aDouble: Double,aString: String?) {}override fun setStringData(strData: String?) {mStrData = strData.toString()}}override fun onCreate() {Log.v(TAG, "onCreate()")super.onCreate()}override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {Log.v(TAG, "onStartCommand()")return super.onStartCommand(intent, flags, startId)}//在onBinder()中啟動一個線程,每1秒輪詢接收客戶端發送過來的數據override fun onBind(intent: Intent): IBinder {mStub.mSetServiceRunning = trueThread {while(mStub.mSetServiceRunning) {try {Thread.sleep(1000);Log.v(TAG, "mStrData:${mStub.mStrData}")} catch (e: InterruptedException) {e.printStackTrace()}}}.start()return mStub		//返回AppAidlInterfaceStub實例}//在unBind里清除運行標志,讓線程能夠退出override fun onUnbind(intent: Intent?): Boolean {Log.v(TAG, "onUnbind()")mStub.mSetServiceRunning = falsereturn super.onUnbind(intent)}override fun onDestroy() {super.onDestroy()Log.v(TAG, "onDestroy()")}
}

需要確保mainappservice在AndroidMainfiest.xml里添加了Service標簽

<applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.Mainapp"tools:targetApi="31"><serviceandroid:name=".MainAppService"android:enabled="true"android:exported="true"></service><!-- .... -->
</application>

六、OtherApp里OtherAppMainActivity添加代碼

package com.example.otherappimport ....class OtherAppMainActivity : AppCompatActivity() {private val TAG = "AIDL-OtherAppMainActivity"private lateinit var binding : ActivityOtherAppMainBindingprivate lateinit var mServiceIntent: Intentprivate var mBinder : IAppAidlInterface? = nullprivate var mICount = 0//創建Service連接和斷開的兩個基礎函數onServiceConnected()和onServiceDisconnected()private val connection = object : ServiceConnection {override fun onServiceConnected(name: ComponentName?, service: IBinder?) {if(mBinder == null) {mBinder = IAppAidlInterface.Stub.asInterface(service)mICount++Log.v(TAG, "onServiceConnected() the time $mICount")try {val strData = "第 $mICount 次連接service成功"mBinder!!.setStringData(strData)} catch (e: RemoteException) {e.printStackTrace()}} else {mICount++Log.v(TAG, "mBinder is not null")}}override fun onServiceDisconnected(name: ComponentName?) {Log.v(TAG, "onServiceDisconnected")}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)enableEdgeToEdge()binding = ActivityOtherAppMainBinding.inflate(layoutInflater)setContentView(binding.root)ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)insets}//新建intent來連接服務端mainapp,Intent的Component設置為Sevice的包名和類名mServiceIntent = Intent()mServiceIntent.component = ComponentName("com.example.mainapp", "com.example.mainapp.MainAppService")// 檢查服務是否存在val resolveInfo = packageManager.resolveService(mServiceIntent, PackageManager.MATCH_DEFAULT_ONLY)if (resolveInfo != null) {// 服務存在,Intent有效Log.v(TAG, "Intent is valid")} else {// 服務不存在,Intent無效Log.v(TAG, "Intent is not valid")}//點擊bind時與service綁定binding.bindServiceBtn.setOnClickListener {val bindResult = bindService(mServiceIntent, connection, Context.BIND_AUTO_CREATE)Log.v(TAG, "bindServiceBtn clicked bindResult:$bindResult")}//點擊unbindg時與service解綁binding.unbindServiceBtn.setOnClickListener {Log.v(TAG, "unbindServiceBtn clicked")unbindService(connection)mBinder = null		//把mBinder清空}}}

在otherapp里新建兩個button用來控制bindService()和unbindService()

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".OtherAppMainActivity"><Buttonandroid:id="@+id/bindService"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Bind Service" /><Buttonandroid:id="@+id/unbindService"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Unbind Service" /></LinearLayout>

七、驗證

把兩個apk安裝并啟動:
image.jpg
點擊bind會建立連接,點擊ubind斷開。再次點擊bind計數會增加
測試結果:

2024-05-28 17:25:31.545  2285-2285  AIDL-Other...inActivity com.example.otherapp                 V  Intent is valid
2024-05-28 17:25:34.879  2285-2285  AIDL-Other...inActivity com.example.otherapp                 V  bindServiceBtn clicked bindResult:true
2024-05-28 17:25:34.882  1505-1505  AIDL-MainAppService     com.example.mainapp                  V  onCreate()
2024-05-28 17:25:34.891  2285-2285  AIDL-Other...inActivity com.example.otherapp                 V  onServiceConnected() the time 1
2024-05-28 17:25:35.885  1505-2363  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 1 次連接service成功
2024-05-28 17:25:36.886  1505-2363  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 1 次連接service成功
2024-05-28 17:25:37.887  1505-2363  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 1 次連接service成功
2024-05-28 17:25:38.888  1505-2363  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 1 次連接service成功
2024-05-28 17:25:39.613  2285-2285  AIDL-Other...inActivity com.example.otherapp                 V  unbindServiceBtn clicked
2024-05-28 17:25:39.621  1505-1505  AIDL-MainAppService     com.example.mainapp                  V  onUnbind()
2024-05-28 17:25:39.623  1505-1505  AIDL-MainAppService     com.example.mainapp                  V  onDestroy()
2024-05-28 17:25:39.888  1505-2363  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 1 次連接service成功
2024-05-28 17:25:42.022  2285-2285  AIDL-Other...inActivity com.example.otherapp                 V  bindServiceBtn clicked bindResult:true
2024-05-28 17:25:42.024  1505-1505  AIDL-MainAppService     com.example.mainapp                  V  onCreate()
2024-05-28 17:25:42.037  2285-2285  AIDL-Other...inActivity com.example.otherapp                 V  onServiceConnected() the time 2
2024-05-28 17:25:43.037  1505-2399  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 2 次連接service成功
2024-05-28 17:25:44.038  1505-2399  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 2 次連接service成功
2024-05-28 17:25:45.039  1505-2399  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 2 次連接service成功
2024-05-28 17:25:45.692  2285-2285  AIDL-Other...inActivity com.example.otherapp                 V  unbindServiceBtn clicked
2024-05-28 17:25:45.701  1505-1505  AIDL-MainAppService     com.example.mainapp                  V  onUnbind()
2024-05-28 17:25:45.702  1505-1505  AIDL-MainAppService     com.example.mainapp                  V  onDestroy()
2024-05-28 17:25:46.040  1505-2399  AIDL-MainAppService     com.example.mainapp                  V  mStrData:第 2 次連接service成功

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18468.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18468.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18468.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI辦公自動化:kimi批量新建文件夾

工作任務&#xff1a;批量新建多個文件夾&#xff0c;每個文件夾中的年份不一樣 在kimi中輸入提示詞&#xff1a; 你是一個Python編程專家&#xff0c;要完成一個編寫關于錄制電腦上的鍵盤和鼠標操作的Python腳本的任務&#xff0c;具體步驟如下&#xff1a; 打開文件夾&…

FFmpeg編解碼的那些事(1)

看了網上很多ffmpeg的編解碼的文章和代碼&#xff0c;發現有很多文章和代碼都過時了&#xff0c;主要還是ffmpeg有很多接口都已經發生變化了。 這里簡單說一下&#xff0c;什么是編碼和解碼。 1.視頻編碼 對于視頻來說&#xff0c;可以理解為多張&#xff08;rgb或者yuv&…

Python散點圖矩陣代碼模版

本文分享Python seaborn實現散點圖矩陣代碼模版&#xff0c;節選自&#x1f449;嫌Matplotlib繁瑣&#xff1f;試試Seaborn&#xff01; 散點圖矩陣&#xff08;scatterplot matrix&#xff09;展示原始數據中所有變量兩兩之間關系&#xff0c;可以規避單一統計指標的偏差&…

二分查找算法詳講(三種版本寫法)原創

介紹: 二分查找算法&#xff08;Binary Search&#xff09;是一種在有序數組中查找目標元素的算法。 它的基本思想是通過將目標元素與數組的中間元素進行比較&#xff0c;從而將搜索范圍縮小一半。 如果目標元素等于中間元素&#xff0c;則搜索結束&#xff1b;如果目標元素小…

Neural Filters:照片恢復

Ps菜單&#xff1a;濾鏡/Neural Filters/恢復/照片恢復 Neural Filters/RESTORATION/Photo Restoration 照片恢復 Photo Restoration借助 AI 強大功能快速恢復舊照片&#xff0c;提高對比度、增強細節、消除劃痕。將此濾鏡與著色相結合以進一步增強效果。 “照片恢復”濾鏡利用…

Scikit-Learn隨機森林

Scikit-Learn隨機森林 1、隨機森林1.1、集成學習1.2、Bagging方法1.3、隨機森林算法1.4、隨機森林的優缺點2、Scikit-Learn隨機森林回歸2.1、Scikit-Learn隨機森林回歸API2.2、隨機森林回歸實踐(加州房價預測)1、隨機森林 隨機森林是一種由決策樹構成的集成算法,它在大多情況…

mac安裝的VMware虛擬機進行橋接模式配置

1、先進行網絡適配器選擇&#xff0c;選擇橋接模式 2、點擊網絡適配器 設置... 3、選擇WiFi&#xff08;我使用的是WiFi&#xff0c;所以選擇這個&#xff09;&#xff0c;注意看右邊的信息&#xff1a;IP和子網掩碼&#xff0c;后續配置虛擬機的ifcfg-ens文件會用到 4、編輯if…

【論文閱讀筆記】The Google File System

1 簡介 Google File System (GFS) 是一個可擴展的分布式文件系統&#xff0c;專為快速增長的Google數據處理需求而設計。這篇論文發表于2003年&#xff0c;此前已在Google內部大規模應用。 GFS不僅追求性能、可伸縮性、可靠性和可用性等傳統分布式文件系統的設計目標&#xf…

benchmark::State benchmark 原理

benchmark::State benchmark::State是Google Benchmark庫中的一個核心類&#xff0c;用于管理單個基準測試的狀態信息和控制基準測試的執行流程。在編寫基準測試時&#xff0c;這個類提供了一套豐富的接口&#xff0c;允許用戶獲取測試循環的次數、調整測試參數、測量時間等&a…

P9 【力扣+知識點】【算法】【二分查找】C++版

【704】二分查找&#xff08;模板題&#xff09;看到復雜度logN&#xff0c;得想到二分 給定一個 n 個元素有序的&#xff08;升序&#xff09;整型數組 nums 和一個目標值 target &#xff0c;寫一個函數搜索 nums 中的 target&#xff0c;如果目標值存在返回下標&#xff0…

企業微信hook接口協議,ipad協議http,語音轉文字

語音轉文字 參數名必選類型說明uuid是String每個實例的唯一標識&#xff0c;根據uuid操作具體企業微信msgid是int要轉文字的語音消息id 請求示例 {"uuid":"a4ea6a39-4b3a-4098-a250-2a07bef57355","msgid":1063645 } 返回示例 {"data&…

電源模塊測試系統怎么測試輸入電壓范圍?

在現代電子設備中&#xff0c;電源模塊的性能直接影響著整個系統的穩定性和效率。其中&#xff0c;電源輸入電壓范圍是指電源能夠接受的輸入電壓的最小值和最大值&#xff0c;它是確保電源正常工作的重要參數。為了提高測試效率和精度&#xff0c;自動化的測試方法逐漸取代了傳…

【Game】Rumble Heroes

文章目錄 1 英雄2 守護獸3 符文4 祝福5 陣容推薦6 Boss7 兌換碼 1 英雄 &#xff08;1&#xff09;力量 神話英雄 圣騎士-烏瑟爾 傳說英雄 雙刀-宮本武藏死亡騎士-阿薩斯冰霜騎士-亞瑟疾風焰刃-緣壹熊貓武僧-阿寶 史詩英雄 大劍-克勞德狂戰士-奎托斯魔山-克里剛獵人-奈辛瓦里 稀…

寶塔部署Java+Vue前后端分離項目

1. 服務器 服務器選擇Linux的CentOS7的版本 2. 寶塔Linux面板 2.1 百度搜索寶塔 2.2 進去之后點擊立即免費安裝 2.3 選擇Linux在線安裝&#xff0c;輸入服務器信息進行安裝(也可以選擇其他方式) 安裝完成之后會彈一個寶塔的應用面板&#xff0c;并附帶有登錄名稱和密碼&…

多模態大模型:系統、趨勢與問題

引言 多模態大模型是當今人工智能領域的熱門方向之一。它不僅能處理文本&#xff0c;還能理解和生成圖像、視頻、語音等多種模態的數據。這種能力使得多模態大模型在自然語言處理、計算機視覺等多個領域展示出巨大的潛力和應用價值。那么&#xff0c;多模態大模型是如何訓練出…

AI菜鳥向前飛 — LangChain系列之十五 - Agent系列:從現象看機制(中篇)一個Agent的“旅行”

Agent基本架構 先談談Agent基本架構概念&#xff0c;如果看得云里霧里&#xff0c;等看完本篇之后&#xff0c;再回頭看就會豁然開朗的&#xff0c;而我盡量寫得更易懂&#xff1a; &#xff09; 這里面會穿插著上一篇的內容&#xff0c;請大家記得往回翻翻&#xff0c;傳送門&…

MySQL 慢查詢優化指南

MySQL 慢查詢優化指南 在現代數據庫管理中&#xff0c;性能優化是一個不可忽視的重要環節。尤其是對于高并發、大數據量的應用&#xff0c;慢查詢可能會成為系統的性能瓶頸。本文將介紹如何查看和優化 MySQL 的慢查詢&#xff0c;幫助你提高數據庫性能。 一、什么是慢查詢&am…

C語言 | Leetcode C語言題解之第118題楊輝三角

題目&#xff1a; 題解&#xff1a; int** generate(int numRows, int* returnSize, int** returnColumnSizes) {int** ret malloc(sizeof(int*) * numRows);*returnSize numRows;*returnColumnSizes malloc(sizeof(int) * numRows);for (int i 0; i < numRows; i) {re…

C#實現計算數據和刷新ListView列表并發執行

下面是一個示例代碼&#xff0c;演示如何在C#中實現計算列表的數據和刷新ListView控件的數據的并發執行&#xff1a; using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms;class Program {static List<int> dataList …

前端API: IntersectionObserver的那一二三件事

IntersectionObserver 基礎 IntersectionObserver 可以監聽一個元素和可視區域相交部分的比例&#xff0c;然后在可視比例達到某個閾值的時候觸發回調。比如可以用來處理圖片的懶加載等等 首先我們來看下基本的格式&#xff1a; const observer new IntersectionObserver(c…