AIDL在Android原始碼中的使用
一:AIDL,Android Interface definition language的縮寫,它是一種android內部程序通訊介面的描述語言,通過它我們可以定義程序間的通訊介面。最近看了下AIDL在Android系統中的用法,在網上看到很多初學的朋友不太明白AIDL的實際作用,android提供了很多程序間通訊的元件,像action、broadcast、contentprovide都可以實現程序間的通訊,為什麼還要用AIDL這個東西呢?
有開發過藍芽或者WIFI應用的朋友肯定都知道,要去操作它必須先獲得一個管理類,比如WIFI的管理類是WifiManager,通過getSystemService(Context.WIFI_SERVICE)就可以得到wifi的管理許可權,這個提供了很多的方法可以讓使用者去操作它,比如開啟wifi可以呼叫setWifiEnabled(true)方法。那這個Manager到底做了什麼工作呢?是怎樣實現開啟wifi的呢?其實這個Manager只是一個管理類,真正幹活的另有其人,是一個叫WifiService的系統服務。在Android系統中有很多的Manager,wifi的管理類叫WifiManager,藍芽的管理類叫BluetoothManager,但是,只要有xxxManager.java,就會有Ixxx.aidl,並且有xxxService.java。這個aidl類就是實現Manager和Service通訊的橋樑。
下面我們以原始碼中的WIFI為例來講述一下AIDL在原始碼中的使用:
首先在這個目錄下是已定義好的一個AIDL檔案
frameworks/base/wifi/java/android/net/wifi/IWifiManager.aidl
關於AIDL的語言規範我就不多說了,其實和Java寫介面差不多(它本來就是一種介面語言)。
然後在frameworks/base/Android.mk中新增一句:wifi/java/android/net/wifi/IWifiManager.aidl。android系統的編譯目標是通過Android.mk來指定的,在這裡加上自定義的aidl檔案系統才會把這個檔案編譯進去,最終生成一個叫IWifiManager
AIDL新增好了後,定義了一個service繼承IWifiManager這個aidl並實現了其中的方法。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
然後在下面這個類中包裝了一下
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiService.java
然後在frameworks/base/core/java/android/content/Context.java檔案中加入一個靜態字串:
public static final String WIFI_SERVICE = "wifi";
最後這個服務在SystemServer中啟動
frameworks/base/services/java/com/android/server/SystemServer.java
private static final String WIFI_SERVICE_CLASS =
"com.android.server.wifi.WifiService";
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
SystemService是android系統跑起來之後就會呼叫的,這裡的意思是把WifiService新增到系統服務中去,並取名字叫Context.WIFI_SERVICE,也就是wifi。這樣看起來是不是很熟悉呢?每個開發人員在開發過程中肯定會呼叫系統服務的,比如電源管理服務:getSystemService(Context.POWER_SERVICE),這個Service也是在這裡新增進去的。android有很多的系統服務,這裡就不一一例舉了,有興趣的朋友可以自行看看這個檔案。
現在aidl添加了,service也添加了,並且新增進了系統服務,那麼還少一個Manager,可以讓第三方程式呼叫的Manager。
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
/**
* Create a new WifiManager instance.
* Applications will almost always want to use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
* the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.
* @param context the application context
* @param service the Binder interface
* @hide - hide this because it takes in a parameter of type IWifiManager, which
* is a system private class.
*/
public WifiManager(Context context, IWifiManager service, Looper looper) {
mContext = context;
mService = service;
mLooper = looper;
mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
}
這個Manager的例項化是通過下面的方法實現的
(WifiManager) context.getSystemService(Context.WIFI_SERVICE)
這個系統的方法和通過aidl的Stub獲取service是相通的,然後在這裡去呼叫這個service的方法,以操作service,這就是aidl的作用。
二:原始碼編譯AIDL Android.mk的寫法:
LOCAL_SRC_FILES := $(call all-java-files-under)
LOCAL_SRC_FILES += \
src/com/asus/cnfindphone/service/persistentdata/IDataBlockService.aidl