Android有兩類API在SDK中不能使用。
第一類就是位於包com.android.internal的API,我將這些API稱為內部API。第二類API就是用@hide標記的類和函數,雖然嚴格說這不是一個API而是一系列隱藏API的集合,我仍然假定這是一個API,稱為隱藏API。
隱藏API的例子
你閱讀android的源碼,就會發現有些常量、函數和類標記為@hide.
這裡有一個隱藏常量的例子,來自WifiManager(source
code of API Level 10).
另外一個例子是隱藏函數setWifiAppEnabled,來自WifiManager(source
code of API Level 10).
所以您只要看到@hide屬性,這就是一個隱藏API。
內部API和隱藏API的不同
隱藏API隱藏是為了防止開發人員使用SDK中未完成或者未穩定(介面和架構方面看)的部分。比如,Bluetooth API在API Level 5(android 2.0)之前就存在,但在API Level 3和4(android 1.5和1.6)中使用@hide隱藏起來了。當該API穩定下來,google的開發人員移除@hide屬性,在API Level 5中就有Bluetooth API了。還有很多東西在Level 4和5之間發生了變化。如果程式依賴於某些隱藏API,可能會在新版本的Android OS上運行出現問題。
而內部API則不計劃對外開放。這是android的內部餐廳,開發人員可以視為黑盒子。這裡面的東西同樣可能發生改變。同樣的,如果您的程式依賴於內部API,在新的Android發布後,可能遇到麻煩。
下面總結它們之間的不同:
隱藏API = 正在開發中;內部API = 黑盒
內部和隱藏API的編譯時間和運行時對比
當您使用Android SDK進行開發時,會引用一個非常重要的jar檔案android.jar。它位於Android SDK的平台目錄SDK_DIR/platforms/platform-X/android.jar(其中X為API Level,可以是5或者10或其它的數字)。在android.jar中,com.android.internal中所有的類移除了,同樣的,所有標記為@hide的類、枚舉、欄位、方法也移除了。
但是當您在裝置中運行應用程式時,載入的是framework.jar(大約等價於android.jar),它沒有被裁減,包含所有的內部類和隱藏API。所以您可以使用反射機制來訪問隱藏API和內部API(當然,這種方法使用起來不太方便,下面我將介紹不使用反射機制訪問這些API的方法)。
關於內部API還有一些特別。Eclipse的ADT外掛程式增加了一條額外規則,禁止使用來自com.android.internal包的任何東西。所以,即使您使用了原始(未裁減)的android.jar,也不容易在eclipse中使用內部API。
您可以自己檢查一下。在eclipse中建立一個新的Android工程(或使用現有的),查看它的引用庫(右鍵點擊工程,Properties –> Java Build Path –> Libraries)。
重要總結:在SDK中內部API和隱藏API處理方式基本上相同(都從android.jar中移除),但內部API在Eclipse ADT外掛程式中顯示禁止了。
不通過反射機制使用內部API和隱藏API
本系列文章的終極目標是給程式員不用反射而使用內部API和隱藏API的方法。如果您完成了在後面文章中的所有步驟,您將可以向象使用官方API那樣使用內部API和隱藏API,沒有必要使用反射。
但是如果您使用這些非公開的API,必須意識到存在一個巨大的風險。首先不能保證這些API在Android OS升級後不會變化,其次也不能保證在不同廠家的不同裝置上有一致的行為。這完全取決您自己。
有以下三種情境:
- 開啟內部API和隱藏API(情境A)
- 僅開啟隱藏API(情境B)
- 僅開啟內部API(情境C)
情境A是情境B和C的綜合。情境B是最簡單的(不需要修改eclipse ADT外掛程式)。
情境A:閱讀1,2,3,4,5
情境B:閱讀1,2,3,5
情境C:閱讀1,2,3,4,5
參考資料:
《使用內部(com.android.internal)和隱藏(@hide)API[第1部分,介紹]》