1. 程式人生 > >android 隱藏API顯式呼叫以及內部資源使用方法

android 隱藏API顯式呼叫以及內部資源使用方法

一、android.jar包

android.jar是我們Android應用開發包,它內部包含了我們在應用開發中需要使用的所有API呼叫。

二、顯式使用 Android 隱藏 API 和內部 API

在進行Android應用開發的時候,一般會選擇指定的編譯版本,選擇編譯版本之後,我們的專案就會使用我們SDK目錄中對應版本的android.jar(sdk/platforms/android-version/android.jar)進行開發,如下圖。

但是有一個問題,Android 有兩種型別的 API 不能通過 SDK 訪問。
(1)com.android.internal 包中的 API,稱之為 internal API。
(2)被標記為 @hide 屬性的類和方法,這是被隱藏的 API,稱之為 hidden API。

1、為什麼這兩種型別的API不能通過SDK來進行訪問?

原因很簡單,就是sdk/platforms/android-version/android.jar被進行了處理,在這個jar中,預設移除了所有的被@hide標識的方法或者類,以及internal包下的類。所以我們在開發的時候這兩種型別的API無法被訪問到。

2、為什麼我們進行反射就能夠呼叫這些類和方法呢?

在我們的Android裝置上,使用的並不是跟我們SDK中相同的jar包,仔細想想,如果裝置上也是使用這個jar包,那麼這兩種型別的API既然被移除了,就說明它根本就不存在,就算是反射也沒法呼叫一個根本不存在的方法呀。

真正的原因是當應用在裝置上執行時,它會載入 /system/framework/framework.jar ,framework.jar 和 android.jar的唯一的區別就是它沒有移除 internal API 和 hidden API,這就說明了為什麼我們可以通過反射呼叫,因為我們開發的SDK中不包含這些API,所以我們無法進行顯式的呼叫,當我們利用反射,程式在裝置上執行的時候,其實是可以找到對應的方法進行呼叫的。

3、也就是說系統有意遮蔽了一些類和方法在我們應用開發的時候不讓我們進行使用,但是這些類和方法是確實存在的,如果我們不想通過反射來進行呼叫,我們該如何處理呢?

方法也很簡單,把我們sdk/platforms/android-version/android.jar這個jar替換成framework.jar就可以了(這裡需要將framework.jar的名字更改成android.jar,然後替換上面sdk中的android.jar),這樣使用包含了隱藏API的jar包進行開發,肯定就可以顯式的呼叫這些方法了。

這裡其實也解釋了為什麼sdk中的隱藏方法不能被顯式呼叫,只能通過反射呼叫,這是如何做到的,之前感覺很神奇,現在是不是豁然開朗了。

前面說了,如果希望顯式的呼叫隱藏API,需要從android裝置中提取/system/framework/framework.jar,把它的名字修改為android.jar,然後將sdk/platforms/android-version/android.jar中的jar進行替換,這樣做無非就是希望sdk使用的是沒有移除 internal API 和 hidden API的jar包。要想得到完整的android.jar其實並不用那麼麻煩,已經有人幫助我們在做這樣的事情了.

上面這個開源專案已經包含了所有版本的完整的android.jar,我們只需要將其替換sdk/platforms/android-version/android.jar就可以了。

具體的做法這個專案的說明也介紹的很清楚,這裡直接貼上過來。

If you also want to include the internal classes or methods, do the following:

Go to <SDK location>/platforms/.
Copy, paste and replace the downloaded hidden API file into this directory, e.g. android-25/android.jar.
Change compileSdkVersion and targetSdkVersion to 25 (for example).
Finally, rebuild your project.

三、使用Android內部資源

這個專案也包含一個Android內部資源訪問的工具包,可以讓你輕鬆的複用到Android內部的所有的Android資源,包含字串、尺寸和顏色等等。

使用方法:

1、專案引入

dependencies {
    compile 'com.anggrayudi:android-hidden-api:0.0.7'
}
repositories {
    maven { url 'https://dl.bintray.com/anggrayudi/maven/' }
    // Or, you can use jCenter instead
    jcenter()
}

2、資源複用

import com.anggrayudi.hiddenapi.r.Rc;

String accept = InternalAccessor.getString(Rc.string.accept);
float sbar_height = InternalAccessor.getDimension(Rc.dimen.status_bar_height);
int notif_color = InternalAccessor.getColor("config_defaultNotificationColor");

參考文章:

歡迎關注微信公眾號:DroidMind
精品內容獨家釋出平臺


呈現與部落格不一樣的技術乾貨