android使用隱藏api的方法(使用被@hide的api)

前言:

一開始需要說明的是,Google之所以要將一些API隱藏(指加上@hide標記的public類、方法或常量)是有原因的。其中很大的原因就是Android系統本身還在不斷的進化發展中。從1.01.1到現在即將問世的Android 2.3.4。 這些隱藏的API本身可能是不穩定的,所以,使用隱藏API,意味着程序更差的兼容性。


    如果要我給出建議的話,最好還是不要使用隱藏的API。不過有時爲了實現Android應用某些特殊的功能或者效果,隱藏的API往往能發揮意想不到的作用。這些API具體能做些什麼事,我就不在這裏舉例了。正好,如果你不知道隱藏API能做什麼的話,那麼還是儘早放棄使用它們吧……


    不想長篇大論,直接進入正題吧。使用隱藏API主要有兩種辦法:一是我在《
Java反射機制的學習》一文中提到的反射的方法得到隱藏API;二是使用源碼編譯時生成的全編譯的jarclasses.jar


    使用反射的方式,在這裏就不詳細介紹了,具體見《
Java反射機制的學習》。利用反射機制使用隱藏API的方法的優點是靈活,能夠在不兼容的系統捕獲異常,而使程序不至於崩潰;缺點是過程太繁雜,而且對於隱藏類的繼承等很難實現。如果需要大量使用隱藏API,使用反射無疑會讓程序員很煩的。


    這篇文章主要要介紹的就是通過導入全編譯的classes.jar包,來實現對隱藏API的使用。這種方法實現簡單,程序員編程也簡單,就像是那些隱藏的APISDK中變得可見了一樣。它的缺點就是兼容性問題,希望使用者引起重視,在使用時考慮清楚。

 

我們使用sdk在開發一個android項目時,往往不能使用被隱藏的api,比如說:
1.我們想實現應用的靜默安裝,我們不能使用

 
1 pm.installPackage(mPackageURI, observer, installFlags,installerPackageName);

2.使用大容量存儲的相關功能時,不能使用

 
1 StorageManager s = (StorageManager) getSystemService(Context.STORAGE_SERVICE);

等等。。
以自帶android自帶的AlarmClock 爲例,導入eclipse後,往往出現很多錯誤,如下圖所示:

例如,上圖中的Intent.ACTION_ALARM_CHANGED 無法訪問,下面我們就找到源代碼看看原因何在?

我所介紹的方法必須要在linux下編譯,但僅僅只是編譯sdk,開發還是在windows下,假如你現在還不會android源碼編譯,請先搞定這個,再往下看。下面的方法二真的是非常的方便,解決了我好多問題,強烈建議你耐心看看。

根據java 編程規範,我們知道這個api (靜態變量)被隱藏掉了,所以在sdk中無法使用。在知道了原因之後,我們有幾種解決方案(強烈建議使用方法二):

方法一:自己將源代碼中的@hide去掉,然後編譯一個sdk來替換默認的sdk。 
在linux上使用  make PRODUCT-sdk-sdk 命令,編譯一個新的sdk出來,注意編譯後其實我們不需要整個sdk,只需要android.jar這個文件替換掉sdk裏的android.jar,例如:筆者的sdk裏的jar對應的目錄爲:

F:/Program Files/Android/android-sdk-windows/platforms/android-8/android.jar

具體編譯sdk的方法是,在linux編譯環境下用命令make PRODUCT-sdk-sdk ,成功後,會有如下提示:

Package SDK: out/host/linux-x86/sdk/android-sdk_eng.stevewang_linux-x86.zip

我們進入到linux編譯環境的 out/host/linux-x86/sdk/android-sdk_eng.stevewang_linux-x86/platforms/android-2.2/目錄下可以看到android.jar 文件。使用此文件替換   F:/Program Files/Android/android-sdk-windows/platforms/android-8/android.jar 即可。替換前記得備份

此方法較爲麻煩,建議使用方法二

方法二:添加framework 編譯出來的classes.jar文件到eclipse的build path 
其實在編譯android的時候,我們將framework 編譯到一個臨時的jar包中了,這個jar包的路徑一般爲:
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
我們只需要在linux上android源代碼目錄下使用make 命令即可生成此文件。

由於這個jar文件中的api 還沒有重新打包,裏面被@hide掉的api並沒有被去掉。所以我們依然能夠引用裏面被@hide的api。而sdk 中的android.jar文件時重新打包生成的,其裏標記有@hide的api已經被去掉了。所以我們把 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar 拷貝到本地pc上。然後在工程中添加此jar包。
具體方法:
1 . 拷貝linux編譯生成的 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar到本機PC。
2,在eclipse的Android項目中,選擇項目屬性->Java Build Path->Libraries->Add Library->User Library->Next-> UserLibraries進入到User Libraries管理界面,點擊New新建一個User Library,比如android_framework,點擊Add Jars把Jar包加入到建立的User Library中,最後點擊OK。
3.選擇項目屬性->Java Build Path->Order and Export,使用右面的“UP”鍵,把所建立的User Libraries移到Android SDK的上面。這樣做的意思就是優先使用classes.jar中的API,其次使用android.jar中的API。爲什麼不直接使用classes.Jar?因爲我在使用時發現,android.jar中有的東西classes.jar中沒有。

如下圖:
 
之後我們的工程錯誤消失了:
 
到此問題基本解決.

發佈了15 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章