如何不通過反射來引用隱藏接口?


Internal接口和hide API

Android has two types of APIs that are not accessible via SDK.
1.  The first one is located in package com.android.internal.
2. The second API type is collection of classes and methods that are marked with @hide javadoc attribute.
The hidden methods can still be accessed via java reflection. The @hide attribute is just part of javadoc(droiddoc also), so the @hide just simply mean the method/class/field is excluded from the API docs.

For example, the checkUidPermission method in ActivityManager.java is @hide.
/** @hide */
public static int checkUidPermission(String permission, int uid) {
    try {
        return AppGlobals.getPackageManager()
                .checkUidPermission(permission, uid);
    } catch (RemoteException e) {
        // Should never happen, but if it does... deny!
        Slog.e(TAG, "PackageManager is dead?!?", e);
    }
    return PackageManager.PERMISSION_DENIED;
}

http://www.cnblogs.com/xirihanlin/archive/2011/06/05/2073118.html

翻譯一下上面的:

Android有兩種類型的API是不能經由SDK訪問的。

第一種是位於com.android.internal包中的API。我將稱之為internal API。第二種API類型是一系列被標記為@hide屬性的類和方法。第一種是不允許調用的,第二種是暫時設定為私有,但是未來可能調用的。

當你使用Android SDK進行開發的時候,你引用了一個非常重要的jar文件——android.jar。它位於Android SDK平台的文件夾中(SDK_DIR/platforms/platform-X/android.jar,其中,X表示API等級)。這個android.jar移掉了com.android.internal包中所有的類,也移掉了所有標記有@hide的類,枚舉,字段和方法。

一般對Hide接口的訪問可以通過反射:,比如:
Class c;
c = Class.forName("android.app.ActivityManager");
Method m = c.getMethod("checkUidPermission", new Class[] {String.class, int.class});
Object o = m.invoke(null, new Object[]{"android.permission.READ_CONTACTS", 10010});

但也可以不使用反射,那就是把hide接口暴露出來,這需要使用framework.jar ,簡單來說,它和android.jar等同,但未移掉internal API和hidden API。

但是當我們去手機里adb shell去獲取framework.jar時,發現它的大小是1k!why?因為L版本引入了Odex優化,
From Lollipop, due to ART, the framework files are in /system/framework/arm/boot.oat file.
Use 'java -jar oat2dex.jar boot boot.oat' and you will get a dex folder containing framework.dex and framework-classes2.dex.

那如何拿到framework.jar呢?

先記錄一下,https://github.com/liudongmiao/ForceStopGB/blob/master/aosp/readme-5.0-z... 里的方法似乎是能用的,
但目前還沒有達到我原設的需求

1. 下載 smali 和 baksmali,https://bitbucket.org/JesusFreke/smali/downloads 這個里面的應該都能在 Java7 上運行。。。至少系統上為了編譯 framework 是安裝的 Java 7
2. 下載 oat2dex,從 https://github.com/testwhat/SmaliEx/releases 下載一個 oat2dex_java7.jar
3. 從 arm 目錄里拿到 boot.oat 和 services.odex
4. 執行 java -jar oat2dex.jar boot boot.oat; 這會在 boot.oat 所在目錄下生成 dex odex 兩個子目錄
5. 執行 java -jar oat2dex.jar services.odex dex/ ; 生成 services.dex
6. 按照教程處理 services.odex 即可:java -jar baksmali.jar -a 22 -b -s services.dex -o services; ...; java -jar smali.jar -a 22 -j 1 -o classes.dex services;
7. 最后生成 services.jar:jar -cvf services.jar classes.dex; 覆蓋,應該能重啟成功

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com