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

本文详细解读Android SDK中的两种特殊API类型:内部API和隐藏API。内部API位于com.android.internal包中,无法通过SDK访问;隐藏API则通过@hide注释标记,允许在特定情况下通过反射或非标准方式访问。文章还探讨了获取framework.jar的方法,以及Lollipop版本后framework文件的存放位置变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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; 覆盖,应该能重启成功
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值