本文轉自51CTO技術社群,先說我現在還沒有接觸Android程式設計。
在Android平台上開發,最熟悉的莫過于Android SDK。SDK給開發者帶來的巨大的便利,使得Android平台的應用開發效率大大提高。不過遺憾的是,Android的功能遠不止SDK暴露的那麼多,還有很多隐藏的東西Google都沒有通過SDK暴露給使用者開發者。檢視Android源代碼時就會發現,這些隐藏的API都有一個共同的特點:類或者方法前都有@hide。如圖:

一、如何隐藏API的?
1)
在正常情況下,即不加@hide的時候,所有的public的類或者方法,在編譯時都會編譯生成到stub library的jar檔案中。這個stub library其實是個空實作,但是它包含了所有的public方法。是以用這個stub library,應用開發者就可以在eclipse中進行開發了。
2)
但一旦加了@hide,那麼在編譯生成stublibrary時,凡是被@hide标記的類或者方法都被移除了。是以應用開發者就無法通過這個stub library“直接”調用被隐藏的類或者方法。如果強行在eclipse裡調用隐藏的類或者方法,則eclipse會報錯。典型的例子就是Android SDK中的android.jar,這個stub library所包含的就是已經被移除的的API。上圖中,ActivityManager的forceStopPackage()方法在Android SDK中是無法找到的。
二、隐藏的API可以調用嗎?
1)
那麼應用開發者可以使用這些隐藏的API嗎? 答案是肯定的。在真實的運作環境中,所有的API都是存在的并且是被實作的。那麼很容易就會想到用“反射”。如果我們已經知道目标類的類名和方法名,以及參數清單,那麼這樣的方法即使被@hide了,我們依然可以通過反射來調用它。對于Java反射,這裡我們不準備展開,不是很了解的同學請自行學習研究。下面是一個反射的例子。
IActivitManageram = ActivityManagerNative.getDefault();
Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class); forceStopPackage.setAccessible(true);
forceStopPackage.invoke(am, yourpkgname);
2)
反射雖好,不過寫起來真麻煩,本來一個調用代碼,一行就可以搞定,但是現在用發射寫的話,需要好多行。有沒有其他更加友善的辦法呢,其實是有的。上面我們提到在Android SDK中的android.jar是一個閹割版,如果我們能生成一個完整版,這個問題就迎刃而解了。方法是現在整套Android源代碼,然後做一次完整的編譯。在out/target/common/obj/JAVA_LIBRARIES/目錄下可以根據需要提取自己所要的stublibrary。以framework為例:将out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar複制到eclipse開發環境中,用userlibrary的方式挂載,使其的優先級比android.jar要高即可。
以下是在eclipse中的設定步驟:
一、需要注意的一些問題
1)
無論是反射還是使用自編譯的stublibrary,隻能解決調用隐藏API的問題,而無法越過權限檢查。
2)
Google之是以将有些API隐藏,有些原因可能是因為這些API屬于内部邏輯,不想對外暴露,也有可能是API接口還未最終确定下來。是以在低版本Android上的隐藏API不一定能在高版本的Android上使用。這點是一定要注意的。也就說隐藏API的相容性比較差。是以利用反射調用隐藏API時,一定要注意根據Android的版本采用不同的方式去反射。
轉載于:https://www.cnblogs.com/xianzhedeyu/articles/Android-Hide-API.html