如何不通过反射来引用隐藏接口?


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