天天看點

Android應用開發中如何使用隐藏的API

Android應用中有時為了實作某些特殊的功能或效果,往往需要使用一些谷歌隐藏的API(加有@hide标記的public類、方法或常量),例如PolicyManager。

        使用Android隐藏的API主要有兩種辦法:1.利用Java反射機制,使用反射的方法得到隐藏API;2.使用源碼編譯時生成的全編譯過的classes.jar包。

        舉例說明,下面的代碼如果直接使用會報錯。

  1. mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);  
  2.        mWindow = PolicyManager.makeNewWindow(mContext);  
  3.        mWindow.setWindowManager(mWindowManager, null, null);  

        1,使用Java反射機制,改為以下代碼,就可以正常使用了。

  1. mWindowManager = (WindowManager) mContext  
  2.                 .getSystemService(Context.WINDOW_SERVICE);  
  3.         // using reflect mechanism to invoke hide api  
  4.         String POLICYMANAGER_CLASS_NAME = "com.android.internal.policy.PolicyManager";  
  5.         try {  
  6.             Class policyClass;  
  7.             policyClass = Class.forName(POLICYMANAGER_CLASS_NAME);  
  8.             Log.i(TAG, policyClass.toString());  
  9.             Method meths[] = policyClass.getMethods();  
  10.             Method makenewwindow = null;  
  11.             // Method makenewwindow = policyClass.getMethod("makeNewWindow");  
  12.             for (int i = 0; i < meths.length; i++) {  
  13.                 if (meths[i].getName().endsWith("makeNewWindow"))  
  14.                     makenewwindow = meths[i];  
  15.             }  
  16.             Log.i(TAG, makenewwindow.toString());  
  17.             mWindow = (Window) makenewwindow.invoke(null, mContext);  
  18.             } catch (Exception e) {  
  19.             e.printStackTrace();  
  20.         }  
  21.         mWindow.setWindowManager(mWindowManager, null, null);  

        2,如果不想修改代碼,就需要使用第二種方法:導入全編譯的classes.jar包。編譯Android架構源碼後,将生成全編譯的classes.jar導入到工程中。使用Eclipse,Android工程添加library(BuildPath -> Add Libraries->User Library->New User Library),将.jar檔案加入添加到library,同時勾選“SystemLibrary”選項,以避免産生“java.lang.OutOfMemoryError:Java Heap Space”錯誤。如果已經正确導入了jar庫,卻仍然找不到隐藏的API。原因可能是Buildclass path order不正确,即android.jar和classes.jar的導入順序不對,具體調節Buildclass path order,選擇Build Path-> Config Build Path->Order and Export,調整自定義的library與android.jar的順序。

        此時,本文最開始的那段代碼不需要再做改動就可以生效了。

        利用反射機制使用隐藏API的方法優點是靈活,能夠在不相容的系統捕獲異常,而使程式不至于崩潰;缺點是過程太繁雜,而且對于隐藏類的繼承等很難實作。如果需要大量使用隐藏API,使用反射無疑會讓人厭煩。

        通過導入全編譯的classes.jar包來實作對隐藏API的使用方法簡單,容易程式設計,就像是那些隐藏的API在SDK中變得可見了一樣,其缺點就是相容性問題,希望使用者引起重視。

        兩種方法各有利弊,請大家斟酌使用。一般來說,谷歌設定隐藏API的主要原因在于Android系統本身還在不斷的進化發展中,這些API可能還不夠成熟、穩定。是以除非特殊情況,應盡量減少對隐藏API的使用。

Ref: http://zhmeup.iteye.com/blog/1119503

繼續閱讀