導航:首頁 > 操作系統 > androidaidl通信

androidaidl通信

發布時間:2023-01-11 06:43:49

1. android AIDL 跨進程(應用)通訊

Android跨應用通訊

Aapp 創建aidl文件

自定義對象為參數的時候需要先創建對應的aidl文件

自定義對象需要 實現Parcelable 介面,進行序列化

創建一個服務,供其他app監聽此服務

為了能讓別的app找到此服務

至此Aapp完畢

Bapp需要擁有和Aapp相同的 aidl文件,及綁定類,包名必須一致

監聽服務

2. android之AIDL介紹

AIDL是一個縮寫,全稱是Android Interface Definition Language,也就是Android介面定義語言。

可以看出,AIDL是一種語言。

設計AIDL這門語言的目的是為了實現進程間通信,尤其是在涉及多進程並發情況下的進程間通信。

每一個進程都有自己的Dalvik VM實例,都有自己的一塊獨立的內存,都在自己的內存上存儲自己的數據,執行著自己的操作,都在自己的那片狹小的空間里過完自己的一生。

每個進程之間都你不知我,我不知你,就像是隔江相望的兩座小島一樣,都在同一個世界裡,但又各自有著自己的世界。

而AIDL,就是兩座小島之間溝通的橋梁。

我們可以通過AIDL來制定一些規則,規定它們能進行哪些交流——比如,它們可以在我們制定的規則下傳輸一些特定規格的數據。

通過這門語言,可以愉快的在一個進程訪問另一個進程的數據,甚至調用它的一些方法,當然,只能是特定的方法。

默認支持的數據類型包括:

AIDL實例文件:

3. 安卓IPC跨進程通訊:AIDL+Retrofit——AndLinker的初步使用

需要用到安卓跨進程通訊,IPC (進程間通信) 的時候,AndLinker是一款Android上的IPC (進程間通信) 庫,結合了 AIDL 和 Retrofit 的諸多特性,且可以與 Rxjava 和 RxJava2 的Call Adapters無縫結合使用。

個人簡單理解就是:簡化AIDL流程的一個第三方庫。使用時需要先了解一下AIDL、retrofit。

以普通Java介面代替AIDL介面

像 Retrofit 一樣生成遠程服務介面的IPC實現

支持的Call Adapters:Call, RxJava  Observable, RxJava2  Observable & Flowable

支持遠程服務回調機制

支持AIDL的所有數據類型

支持AIDL的所有數據定向tag:in,out,inout

支持AIDL的oneway關鍵字

在服務端以及客戶端的項目根目錄的build.gradle中添加jcenter()倉庫

在App的build.gradle中添加如下依賴

AndLinker支持AIDL所有數據類型:

Java語言中的所有原始類型 (如:int,long,char,boolean,等等)

String

CharSequence

Parcelable

List (List中的所有元素必須是此列表中支持的數據類型)

Map (Map中的所有元素必須是此列表中支持的數據類型)

介面里的方法就是按需求需創建。這里只舉幾個簡單的示例。

4. android開發aidl何時使用

1.什麼是aidl:aidl是 Android Interface definition language的縮寫,一看就明白,它是一種android內部進程通信介面的描述語言,通過它我們可以定義進程間的通信介面

icp:interprocess communication :內部進程通信

2.既然aidl可以定義並實現進程通信,那麼我們怎麼使用它呢?文檔/android-sdk/docs/guide/developing/tools/aidl.html中對步驟作了詳細描述:


--1.Create your .aidl file - This file defines an interface (YourInterface.aidl) that defines the methods and fields available to a client.

創建你的aidl文件,我在後面給出了一個例子,它的aidl文件定義如下:寫法跟java代碼類似,但是這里有一點值得注意的就是它可以引用其它aidl文件中定義的介面,但是不能夠引用你的java類文件中定義的介面

package com.cao.android.demos.binder.aidl;

import com.cao.android.demos.binder.aidl.AIDLActivity;

interface AIDLService {

void registerTestCall(AIDLActivity cb);

void invokCallBack();

}

--2.Add the .aidl file to your makefile - (the ADT Plugin for Eclipse manages this for you). Android includes the compiler, called AIDL, in the tools/ directory.

編譯你的aidl文件,這個只要是在eclipse中開發,你的adt插件會像資源文件一樣把aidl文件編譯成java代碼生成在gen文件夾下,不用手動去編譯:編譯生成AIDLService.java如我例子中代碼

--3.Implement your interface methods - The AIDL compiler creates an interface in the Java programming language from your AIDL interface. This interface has an inner abstract class named Stub that inherits the interface (and implements a few additional methods necessary for the IPC call). You must create a class that extends YourInterface.Stub and implements the methods you declared in your .aidl file.

實現你定義aidl介面中的內部抽象類Stub,public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService

Stub類繼承了Binder,並繼承我們在aidl文件中定義的介面,我們需要實現介面方法,下面是我在例子中實現的Stub類:

private final AIDLService.Stub mBinder = new AIDLService.Stub() {


@Override

public void invokCallBack() throws RemoteException {

Log("AIDLService.invokCallBack");

Rect1 rect = new Rect1();

rect.bottom=-1;

rect.left=-1;

rect.right=1;

rect.top=1;

callback.performAction(rect);

}


@Override

public void registerTestCall(AIDLActivity cb) throws RemoteException {

Log("AIDLService.registerTestCall");

callback = cb;

}

};

Stub翻譯成中文是存根的意思,注意Stub對象是在被調用端進程,也就是服務端進程,至此,服務端aidl服務端得編碼完成了。


--4.Expose your interface to clients - If you're writing a service, you should extend Service and override Service.onBind(Intent) to return an instance of your class that implements your interface.

第四步告訴你怎麼在客戶端如何調用服務端得aidl描述的介面對象,doc只告訴我們需要實現Service.onBind(Intent)方法,該方法會返回一個IBinder對象到客戶端,綁定服務時不是需要一個ServiceConnection對象么,在沒有了解aidl用法前一直不知道它是什麼作用,其實他就是用來在客戶端綁定service時接收service返回的IBinder對象的:

AIDLService mService;

private ServiceConnection mConnection = new ServiceConnection() {

public void onServiceConnected(ComponentName className, IBinder service) {

Log("connect service");

mService = AIDLService.Stub.asInterface(service);

try {

mService.registerTestCall(mCallback);

} catch (RemoteException e) {


}

}


public void onServiceDisconnected(ComponentName className) {

Log("disconnect service");

mService = null;

}

};

mService就是AIDLService對象,具體可以看我後面提供的示例代碼,需要注意在客戶端需要存一個服務端實現了的aidl介面描述文件,但是客戶端只是使用該aidl介面,不需要實現它的Stub類,獲取服務端得aidl對象後mService = AIDLService.Stub.asInterface(service);,就可以在客戶端使用它了,對mService對象方法的調用不是在客戶端執行,而是在服務端執行。


4.aidl中使用java類,需要實現Parcelable介面,並且在定義類相同包下面對類進行聲明:


上面我定義了Rect1類

之後你就可以在aidl介面中對該類進行使用了

package com.cao.android.demos.binder.aidl;

import com.cao.android.demos.binder.aidl.Rect1;

interface AIDLActivity {

void performAction(in Rect1 rect);

}

注意in/out的說明,我這里使用了in表示輸入參數,out沒有試過,為什麼使用in/out暫時沒有做深入研究。

轉載

5. Android開發藝術探索讀書筆記之AIDL

AIDL是 Android Interface definition language的縮寫,一看就明白,它是一種android內部進程通信介面的描述語言,通過它我們可以定義進程間的通信介面

AIDL可以實現跨進程的方法調用。定義進程通信介面供服務端和客戶端調用。

在AIDL文件中並不是所有數據類型都可以使用。只支持下列數據類型

默認情況下AIDL的調用過程是同步的,所以不能直接進行比較耗時的操作,否則容易導致客戶端ANR。如果需要進行非同步操作,在服務端不需要另起線程,但是在客戶端需要另起線程訪問遠程方法,再通過Handler通知到UI線程即可!

6. android之AIDL

AIDL 是 Android 跨進程通信的一種方式

所有的非基本參數都需要一個定向 tag 來指出數據的流向,不管是 in , out , 還是 inout 。基本參數的定向 tag 默認是並且只能是 in

Book.kt

Book.aidl

IOnNewBookArrivedListener.aidl 用於添加監聽

客戶端發起遠程請求,會調用 IBookManager.Stub.Proxy 的對應實現方法,在這個方法里,創建了 Parcel 對象 _data、輸出型 Parcel 對象 _reply 和返回值對象 List,將參數寫入 _data 中,調用 transact 方法來發起 RPC ,同時當前線程掛起,然後服務端的 onTransact 方法會被調用,在 onTransact 中,調用服務端提供的服務方法,寫入結果,回到客戶端的 transact ,將結果從 _reply 讀出並返回

7. android進階-AIDL之介面注冊/解注冊

AIDL-基本使用
AIDL-自定義數據類型
AIDL-修飾符in,out,inout
AIDL-重連方法
AIDL-介面注冊/解注冊
AIDL-連接池

為什麼要特意講解一下介面的注冊與取消注冊呢,因為在使用AIDL進程跨進程通信的時候, 每次傳遞的介面對象在內存中的地址都是不一樣的 ,所以在注冊了之後,無法使用常規的方式去取消, 因為注冊和解注冊傳遞的介面地址都不一樣 ,系統無法識別

由於上面的問題,AIDL中提供了一個專門解決上述情況的類 RemoteCallbackList ,其工作原理就是:

首先,在前面講解 AIDL的基本使用 的基礎上先增加新的AIDL介面以及注冊和解注冊方法:

然後就是 RemoteCallbackList 的使用方法了:
注冊/解注冊很簡單

接著是使用介面的方式:

ps: 需要注意的是 beginBroadcast() 方法和 finishBroadcast() 方法 必須配合使用 ,哪怕只是簡單的獲取集合大小

使用AIDL進行跨進程間通信中,往往我們是需要注冊監聽,讓服務端通知的,但是服務端也必須提供解注冊的方法,不然客戶端如果離開某個界面不想再接受消息了,雖然直接離開不做處理客戶端這邊不會出錯,但是服務端那邊的監聽集合還存在之前的,那麼就會浪費系統資源,所以有注冊監聽的時候,最好也要實現解注冊的方法

https://github.com/returntolife455/DemoList

《Android開發藝術探索》

8. Android:AIDL進程間通信基本框架

在某些業務場景下,我們需要在應用中單獨開啟一個進程進行一些操作。比如性能監控,如果讓原始業務和性能監控本身的業務跑在同一個進程下,那麼就會導致性能統計的數據的失真。

而進程間通信,一般採用AIDL機制的客戶端與服務端通信。

AIDL只能傳遞如下幾類數據:

當傳遞自定義 Parcelable 時,有三處地方需要注意:

當傳遞其他 aidl 介面時,同樣必須要 import 這個 aidl 文件

編寫完 aidl 文件後,make一下工程,會在 build 下的 generated 下的 source 下的 aidl 目錄生成對應的介面類文件。aidl 介面其實就是 API 介面,通過實現對應介面類的 Stub 子類來實現具體的 API 邏輯;通過對應介面類的 Stub 子類的 asInterface 方法得到具體的實現類,調用具體的 API 方法。

一個基本的客戶端服務端的通信結構一般包括如下功能

客戶端的功能

服務端的功能

客戶端的相關功能實現比較簡單,麻煩的是服務端的功能。因為 AIDL 介面定義的都是服務端的介面,是由客戶端來調用的。而想要實現服務端反向調用客戶端則需要通過其他手段實現。

想要實現服務端主動連接客戶端,最好的辦法就是 服務端發送廣播,客戶端收到廣播後再主動連接服務端 ,通過這種方式變相地實現服務端主動連接客戶端的功能

想要實現服務端主動斷開客戶端,除了上面 發送廣播是一種實現方式外,還可以通過 android 的系統API RemoteCallbackList,用包名作為key值來注冊遠程回調介面的方式,讓服務端持有客戶端的回調介面,服務端調用回調介面,客戶端在回調介面中實現主動斷開服務端 ,通過這種方式變數地實現服務端主動斷開客戶端的功能。而採用後者會顯得更加優雅

既然所有的操作歸根結底都是由客戶端來完成的,那麼客戶端必須得有如下的功能模塊:

服務端必須得有的功能模塊:

那麼,整體的通信流程就是如下的步驟:

首先是通信的 aidl 介面定義

然後是客戶端的連接操作與斷開連接操作,包括廣播接收者的注冊以及回調介面的實現

然後是客戶端的拉取數據和推送數據操作

接著是服務端的 iBinder 介面的實現,完成回調介面的注冊、業務子線程的開啟和關閉、數據的推送和數據的拉取操作

然後是服務端的主動連接和主動斷開連接操作

最後是服務端的 onUnbind 方法的實現,對回調介面進行反注冊

服務端模仿 FloatViewPlugin 自定義插件,實現 IServicePlugin 介面,定製個性化的懸浮窗插件

客戶端在 Appliaction 的 onCreate方法中初始化

在 MainActivity 上實現連接、斷開、數據通信

9. h5調用Android的aidl

由於AIDL是在一個進程裡面發起並調用另外一個進程的方法或者數據,而進程間的通信主要是由transact發起的,Binder的API都是同步的,transact方法會等待服務端進程的onTransact方法返回後才進行返回。所以默認情況下,AIDL的調用過程就是同步的。因此,如果在主線程中調用遠程服務端的耗時操作方法,則比較容易出現ANR。

閱讀全文

與androidaidl通信相關的資料

熱點內容
python代碼精簡 瀏覽:455
文件加密了怎麼找到了 瀏覽:193
jellyfin插件怎麼選擇主伺服器 瀏覽:836
asp用戶注冊源碼 瀏覽:48
什麼是照片壓縮文件 瀏覽:392
java調用js代碼 瀏覽:979
崑山市民app怎麼修改身份信息 瀏覽:779
php登陸次數 瀏覽:744
python字元轉成數字 瀏覽:822
海川用的是什麼伺服器 瀏覽:376
口才是練出來的pdf 瀏覽:458
雲伺服器哪個公司性價比高 瀏覽:517
源碼論壇打包 瀏覽:558
php怎麼做成word 瀏覽:692
python批量生成密鑰 瀏覽:492
程序員要不要考社區人員 瀏覽:150
app的錢怎麼充q幣 瀏覽:814
android銀行卡識別 瀏覽:756
怎麼在app投放廣告 瀏覽:11
手機文件管理怎麼看app名稱 瀏覽:192