1. 程式人生 > >Kotlin--›IPC跨程序通訊之Messager(雙向通訊)

Kotlin--›IPC跨程序通訊之Messager(雙向通訊)

Android跨程序通訊有很多種方式, 具體的大家百度一下就知道了. AIDL就是其中一種;

本文介紹AIDL系統輕量封裝Messager的使用.

涉及到的類

類名 作用
Service 程序載體
Handler 處理訊息, 關聯MessageMessenger的通道
Message 需要傳送的訊息實體, 傳輸資料的載體
Messenger 傳送訊息, 通訊的實體類, 用來send Message
Parcelable 自定義需要傳輸的資料

1.服務端編寫

class RemoteService : Service() {

    val
remoteHandler: Handler = object : Handler() { override fun handleMessage(msg: Message) { super.handleMessage(msg) //注意此處, 必須的設定, 否則自定義的MsgBean類, ClassNotFoundException異常 msg.data.classLoader = RemoteService.javaClass.classLoader val bean:MsgBean = msg.data.getParcelable<MsgBean>("data"
) if (msg.what == 3) { //測試死迴圈, 不會出現anr Thread.sleep(10_000) } //收到訊息後, 可以通過replyTo物件, 回覆客戶端. msg.replyTo?.let { //java.lang.RuntimeException: Can't marshal callbacks across processes. // it.send(Message.obtain(null) {
// L.e("runnable") // }) sendText(it, 10_001, "服務端已收到訊息.${msg.what}") } } } private fun sendText(messenger: Messenger, what: Int, text: String) { messenger.send(Message.obtain(null, what).apply { replyTo = remoteMessenger //用來答覆的Messenger data = Bundle().apply { putParcelable("data", MsgBean(text)) //資料建議放在 Bundle中 } }) } private val remoteMessenger: Messenger init { remoteMessenger = Messenger(remoteHandler) } override fun onBind(p0: Intent?): IBinder { return remoteMessenger.binder } }

幾點需要注意的:
1. 靜態資料在服務端修改後, 客戶端獲取不到修改後的值
2. 自定義的資料, 儘量使用 Bundle 包一層
3. Bundle需要設定classLoader, 否則會出現ClassNotFoundException

不要忘了在AndroidManifest.xml宣告:

<service
   android:name=".RemoteService"
   android:process=":remote"/>

如果android:process的名字, 有:號, 則這個程序和主程序是 父子關係 否則就是 兄弟關係

2.客戶端編寫

基礎的物件宣告:

val localHandler = object : Handler() {
    override fun handleMessage(msg: Message) {
        super.handleMessage(msg)
        L.e("客戶端: handleMessage ->${RemoteService.test_static_data} ${msg.what} ${msg.obj}")

        msg.data.classLoader = classLoader //注意:同樣的設定

        showText("收到服務端訊息:${RemoteService.test_static_data} ${msg.what} ${msg.obj} ${msg.data.getParcelable<MsgBean>("data")}")
    }
}

val localMessenger = Messenger(localHandler)

var remoteMessenger: Messenger? = null

啟動服務端:

val remoteServiceIntent = Intent(this, RemoteService::class.java)
val remoteCon = object : ServiceConnection {
    override fun onServiceDisconnected(p0: ComponentName?) {
        L.e("call: onServiceDisconnected -> $p0")

        showText("onServiceDisconnected_${p0}")

        remoteMessenger = null
    }

    override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
        L.e("call: onServiceConnected -> $p0 $p1")
        showText("onServiceConnected_${p0}")

        remoteMessenger = Messenger(p1)
        sendText(1, "客戶端連線成功...")
    }
}
bindService(remoteServiceIntent, remoteCon, Service.BIND_AUTO_CREATE)

傳送訊息:

private fun sendText(what: Int, text: String) {
  remoteMessenger?.send(Message.obtain(null, what).apply {
      replyTo = localMessenger
      data = Bundle().apply {
          putParcelable("data", MsgBean(text))  //用Bundle包一層
      }
  })
}

也許你還想學習更多, 來我的群吧, 我寫程式碼的能力, 遠大於寫文章的能力:

聯絡作者

請使用QQ掃碼加群, 小夥伴們都在等著你哦!

關注我的公眾號, 每天都能一起玩耍哦!

相關推薦

Kotlin--›IPC程序通訊Messager(雙向通訊)

Android跨程序通訊有很多種方式, 具體的大家百度一下就知道了. AIDL就是其中一種; 本文介紹AIDL系統輕量封裝Messager的使用. 涉及到的類 類名 作用

Kotlin--›IPC程序通訊AIDL(雙向通訊)

Messenger是系統對aidl一個輕量封裝, 方便使用, 但是有一定侷限性. 本文介紹直接介紹aidl的使用, 讓跨程序通訊就跟本地呼叫一樣爽. 準備 定義呼叫介面 建立相應的自定義資料Bea

QAxWidget 呼叫ocx控制元件 js雙向通訊

1 示例: QAxWidget 載入 IE外掛  第一步 載入ie控制元件void CActivexWidget::InitActiveX() //其中 CActivexWidget 派生自QAxWidget{setControl("Shell.Explorer");//HK

使用 Messenger實現與獨立程序的Service的雙向通訊

1、先對比一下,咱們要知道什麼時候使用Messenger更合適,下面是官網給出的解釋。 Messenger 與 AIDL 比較  當您需要執行 IPC 時,為您的介面使用  要比使用 AIDL 實現它更加簡單,因為  會將所有服務呼叫排入佇列,而純粹的 AIDL 介面會同

PLC通訊藍芽通訊

目錄 四、測試 一、實驗架構 如圖所示,其中 水迴圈水箱:上下兩個水箱,其中安裝多個感測器。 水迴圈系統:採集水迴圈水箱資料,顯示並通過藍芽傳給智慧感知系統。(PLC採用WAGO 750-881) 智慧感知系統:接收水迴圈系統中藍芽

Android 網路通訊HTTP請求通訊

Android網路通訊平臺支援還是比較豐富的,除了相容J2ME中的java.netapi外還提供了一下Android平臺獨有的類android.net這個Package。一種是GET方式,一種是POST方式。然後HttpClient的Get/Post方式。似乎更強大的是org.apache.http類,這個

Python學習【第20篇】:互斥鎖以及程序之間的三種通訊方式(IPC)以及生產者個消費者模型 python併發程式設計程序1-----------互斥鎖與程序間的通訊

python併發程式設計之多程序1-----------互斥鎖與程序間的通訊 一、互斥鎖 程序之間資料隔離,但是共享一套檔案系統,因而可以通過檔案來實現程序直接的通訊,

程序通訊AIDL-----不同應用程式之間程序

AIDL,通俗來說就是兩個Android應用要進行通訊,且不能通過網路雲伺服器的方式進行資料互動,只能呼叫本地函式庫的機制來實現,這時Android系統提供AIDL的機制來實現Android的跨程序通訊(使用者程序之間是相對封閉的,無法直接訪問資料)。 我們先不

【朝花夕拾】效能優化篇(八)AIDL與Android程序通訊

        一、Linux程序間通訊   1、程序隔離         在作業系統中,程序與程序間的記憶體和資料都是不共享的。兩個程序就好像大海中相互獨立的兩個島嶼,各自生活在互相平行的兩個世界中,互不干擾,各

Android 程序雙向通訊(Messenger與AIDL)詳解

今天這篇文章主要講一下Messenger與AIDL的區別、優缺點以及各自的使用方法。 Messenger與AIDL的異同 一、Messenger與AIDL相同點 1.都與IPC的呼叫有關; 2.Messenger 是一種輕量級的

Android使用AIDL實現程序通訊IPC

前言:在還沒有做任何一件事情之前,千萬不要覺得這件事情很難,因為還沒有開始做內心就已經對這件事情產生了恐懼,這將會阻止你的進步,也許當你動手開始做了這件事後發現其實並不是很難。 一、 AIDL概述 含義:AIDL(Android Interface Defi

Android面試篇IPC機制[程序之間的通訊]

簡介 IPC Inter-Process Communication 跨程序通訊,兩個程序之間進行資料交換的過程 在Android中的多程序一般指一個應用中存在多個程序的情況,下面討論一個應用中多程序

Android進階——Android程序通訊機制Binder、IBinder、Parcel、AIDL

前言 Binder機制是Android系統提供的跨程序通訊機制,這篇文章開始會從Linux相關的基礎概念知識開始介紹,從基礎概念知識中引出Binder機制,歸納Binder機制與Linux系統的跨程序機制的優缺點,接著分析Binder的通訊模型和原理,而Bin

【朝花夕拾】Android效能篇(七)Android程序通訊

前言        Android系統的執行由大量相互獨立的程序相互協助來完成的,所以Android程序間通訊問題,是做好Android開發高階工程師必須要跨過的一道坎,也是面試時經常被問及到的知識點。但是,我們是否真的清楚,Android中都有哪些方式實現跨程序通訊

Linux程序通訊訊息佇列的雙向通訊

  上一篇部落格我寫了程序間通訊基於管道的通訊,但是管道的通訊無疑有很大的缺點,最顯著的就是隻能單向通訊,例如:server向client發訊息,client無法回覆;第二個就是隻能在有血緣關係的程序間進行通訊,雖然命名管道解決了第二點,但是第一點還是一個很大的

面試題:IPC程序通訊

Q1:IPC基礎及概念? Q2:Android中程序和執行緒的關係?區別? Q3:為何需要進行IPC?多程序通訊可能會出現什麼問題? Q4:Android中IPC方式有幾種? 為何新增Binder來作為主要的IPC方式? Q5:使用Binder進行資料傳輸的具體過程? Q6:

linux系統——IPC程序通訊訊號量

一、訊號量引出 當我們編寫的程式使用執行緒的時候,總是有一部分臨街程式碼,需要確保只有一個程序(或一個執行緒)可以進入這個臨街程式碼並擁有對資源的獨佔式訪問 ——》檔案鎖,提供了一個原子化的檔案建立方法,它允許一個程序通過一個令牌(新建立的檔案)來取得成功,這個

Android TV開發-桌面 程序通訊(IPC) 詳解

@[TOC] 1. 寫在前面 Android 程序間通訊 的 幾種方式: 四大元件間傳遞Bundle 使用檔案共享方式,多程序讀

IPC進程間通訊三】內存映射文件Mapping File

eas -h 大小 b2c iss ipc etl enter bject IPC進程間通信+共享內存Mapping IPC(Inter-Process Communication。進程間通信)。

Android學習--程序共享數據內容提供其探究

bundle 風險 重點 比較 約束 length 通訊 this provide 什麽是內容提供器? 跨程序共享數據之內容提供器,這是個什麽功能?看到這個名稱的時候最能給我們提供信息的應該是“跨程序”這個詞了,是的重點就是這個詞,這個內容提供器的作用