搜尋此網誌

2013-10-28

AIDL and Remote Service

作者: Joy Song

基於安全上的考量,Android的每個AP都會跑在自己的process上,不同的process是無法直接溝通的,必須要透過Android所提供的某些機制 (Intent, Binder) 才能達到溝通的訊息。

因此,Android提供了一種IPC的實作方式AIDL來達到讓兩個不同process也能相互溝通的目的。實作的方法很簡單,以下提供一個簡單的範例,另外AIDL有些要注意的地方,這邊也提出來跟大家分享。

實作範例


1. 定義 aidl 檔案



2. 在自己的service.java檔案實作這個function就可以使用,這邊可以稍微注意一下,不論service裡發生何種exception,他只會丟出一種RemoteException出來,

3. 在ServiceConnection裡就可以拿到這個interface


另外aidl只支援幾種type:

· - All primitive types in the Java programming language (such as int, long, char, boolean, and so on)

· - String

· - CharSequence

· - List

· - Map


<Directional Tag>


這邊特別提到,在AIDL裡有一個叫做directional tag,這個tag有包含三個變量可以設置:分別是 in、out 和 inout 。只要是非基本數據類型,就必須要加上這個tag。 如果沒有加,compile的時候就會有error提示訊息。

從字面上比較好理解,in就表示是由client設置,送資料給server端,那為何還會有out跟inout兩種呢?

這邊用幾個例子說明

in: in tag,由client送資料給server:
boolean dumpSettingstoFiles(in List<String> pref);
out: out tag 表示這是一個output only的參數,也就是不透過client端送資料,但是server端會把資料填到這參數裡面:
void copyFramArray(in byte[] source, out byte[] dest);
inout: inout tag表示參數同時會有input以及output,可以由client送資料給server,server也可以用這個變量來存放資料
void setFilestoArray(inout char[] chars);

以上的設定是必須的,那對performance來說會有重要的影響,在官方的文件就有提到這麼一句話

· You should limit the direction to what is truly needed, because marshalling parameters is expensive.

那甚麼是marshalling呢? 它包含了 serialized、transmitted、received 和 deserialized。Directional tag會讓binder去忽略marshalling階段而得到更好的performance.

一般的情況下AP也有可能有自己的service在背景執行一些動作,這個時候service和AP預設是跑在同一個process上的,如果今天有其他需求需要讓service和AP跑在不同process時,

只需要在manifest上加上這行參數isolatedProcess設為true就可以了


最後總結何時會需要用到AIDL,他的使用時機有兩點

1. If you allow clients from different applications to access your service for IPC.
2. If you want to handle multithreading in your service.
當需要透過AIDL來存取Service時,上述的一些心得讓大家參考~~

Reference:
http://developer.android.com/guide/components/aidl.html
http://developer.android.com/guide/topics/manifest/service-element.html#isolated

沒有留言 :

張貼留言