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

【引言】:我在做android softap的时候看到android.net.wifi.WifiManager的很多方法不能被应用程序调用。通过查看源码,我发现这些函数的修饰符是public,而且整体上跟普通公共函数没有任何区别,要说有区别就是函数注释说明里有一行@hide。我当时就好奇了,难道android的编译器会分析注释部分,给这个函数加了什么特殊标记导致应用程序不能访问。后来找到这篇文章,才发现只是在编译时和运行时链接了不同的库而已,而在编译时链接的库不含internal和这些注释中标明hide的函数。

Android有两种类型的API是不能经由SDK访问的。第一种是位于com.android.internal包中的API, 我将称之为internal API;第二种API类型是一系列被标记为@hide属性的类和方法。从严格意义上来讲,这不是一个单一的API,而是一组小的被隐藏的API,但我仍将 其假设为一种API,并称之为hidden API。

1、Android为什么要隐藏Internalhidden API

Hidden API之所以被隐藏,是想阻止开发者使用SDK中那些未完成或不稳定的部分(接口或架构)。举个例子,Bluetooth API在API 5(Android 2.0)上才开放;在API 3 和4上都是用@hide属性隐藏了。当这些API被验证和清理后,Google的开发者会移除@hide属性,并让其在API 5官方化。很多地方在API 4 和5之间发生了变化。如果你的程序依赖某些隐藏的API,当其部署到新的平台上时,就有可能陷入困境。

对 于internal API来说,从来都没有计划将其开放出来。它就是Android的“内部厨房”,对开发者来说,应该将其视作黑盒。凡事都会有变化的。如果你依赖某些 internal API,也有可能在新的Android release上,这些internal API发生变化,从而令你失望。

2、Internalhidden API的编译时 vs. 运行时:

当 你使用Android SDK进行开发的时候,你引用了一个非常重要的jar文件——android.jar。它位于Android SDK平台的文件夹中(SDK_DIR/platforms/platform-X/android.jar,其中,X表示API等级)。这个 android.jar移掉了com.android.internal包中所有的类,也移掉了所有标记有@hide的类,枚举,字段和方法。

但当你在设备上启动应用程序时,它将加载framework.jar(简单来说,它和android.jar等同),而其未移掉internal API和hidden API。(但它对开发者来说,并不能友好地访问,因此,我将向大家展示不通过反射如何使用这些API)。

关于 internal API,还有一件事需要说明。Eclipse的ADT插件增加了一个额外的规则,那就是禁止使用com.android.internal包中的任何东 西。所以,即便是我们可以拿到最原始的android.jar(未删减版),也没有轻松的办法通过Eclipse使用这些internal API。

你可以亲自检查一下。创建一个新的Android工程(或者使用已有的)。查看一下它引用的类库(右击project Properties –> Java Build Path –> Libraries)。

重要的总结:internal和hidden API在SDK中是按照一样的方式处理的(都从android.jar中移除了),但internal API更惨的是,还被Eclipse的ADT插件显式禁止了。

3、不通过反射使用internalhidden API:

如果我们想调用这些隐藏的API,常用的方式是采用反射机制。然而,这些文章的终极目标是让开发者能够不通过反射使用Internal和Hidden API。如果你完成了接下来部分中描述的步骤,你将能使用这些Internal和Hidden API,如同公开的API。你不再需要使用反射。

【注】:如果你正在使用这些非公开的API,你必须知道,你的程序有着极大的风险。基本上,无法保证在下一次的Android OS更新时,这些API不被破坏,也无法保证不同的运营商有着一致的行为。你自己决定吧。

接下来有三个场景:

  • 1. Internal 和hidden API都可用(场景A)
  • 2. 只Hidden API可用(场景B)
  • 3. 只Internal API可用(场景C)

场景A是B、C的总和。场景B是最简单的一个(不需要对Eclipse的ADT修改)。

  • 场景A:阅读Part1, 2, 3, 4, 5
  • 场景B:阅读Part1, 2, 3, 5
  • 场景C:阅读Part1, 2, 3, 4, 5

3.1、如何得到原版android.jar:

我们需要修改android.jar,这样它才能包含所有的*.class文件(包括internal和hidden API类)。有两种办法:

  • 1) Android是一个开源工程。我们可以下载源码并搭建编译环境,这样它就不能移除那些internal和hidden的类了。这个办法比较困难;
  • 2) 每个模拟器或真机在运行时都会有一个等同android.jar的东西。我们可以从这里拿到jar文件,提取出原始的.class文件,并拷贝到Android SDK的android.jar中。

我将采用方案2。它易于开始,还不需要搭建Linux环境及编译环境等。

3.2、从设备上获取framework.jar:

你可以使用命令行(adb pull)从模拟器或设备上下载文件,或者使用DDMS(借助Eclipse或SDK中的应用)。注意:模拟器通常在.dex文件中包含代码,而真机一般在优化版的dex文件中包含代码——odex文件。操作odex文件比较困难,这也是为什么我选择模拟器的原因。与Android SDK中的android.jar等同的文件是framework.jar。这个文件位于设备的:/system/framework/framework.jar

基于以上,我们采用如下命令:

adb pull /system/framework/framework.jar

当framework.jar从设备上下下来之后,重命名为framework.zip并解压到独立的文件夹中,其中classes.dex就是我们需要的文件。

3.3、创建framework-classes.zip:

首先,我们需要把.dex文件转换成.jar格式。你可以使用通用的工具dex2jar。只需要运行:

dev2jar classes.dex

当转换结束时,你应该得到了classes.dex.dex2jar.jar文件。重命名为framework-classes.zip。使用zip查看器,进入到framework-classes.zip/com/android/internal/:

恭喜你,你已经拥有了所有的.class文件,包括internal和hidden API(尽管截图只确认了internal部分)。

3.4、创建original-android.jar:

Android SDK的android.jar位于ANDROID_SDK/platforms/android-X/android.jar(X表示API等级)。拷贝android.jar成custom-android.jar。解压至custom-android文件夹。将framework- classes.zip中所有的.class文件拷贝到custom-android文件夹中(你需要覆盖所有已经存在的.class文件)。然后,压缩custom-android文件成original-android.zip。重命名为original-android.jar。

3.5、步骤总结:

  • 1. 选择你的目标平台X
  • 2. 创建目标平台X的模拟器
  • 3. 启动模拟器,下载/system/framework/framework.jar
  • 4. 重命名framework.jar -> framework.zip
  • 5. 从framework.zip中抽取classes.dex
  • 6. 使用dex2jar工具,将其转换成classes.jar
  • 7. 重命名classes.jar -> framework-classes.zip
  • 8. 拷贝android.jar –> custom-android.zip
  • 9. 解压custom-android.zip至custom-android文件夹
  • 10. 将framework-classes.zip中所有文件拷贝至custom-android文件夹(覆盖存在的文件)
  • 11. 压缩custom-android文件夹成original-android.zip
  • 12. 重命名original-android.zip -> original-android.jar

4、总结:

我 们还原了android.jar,使其包含所有的internal和hidden API的.class文件。这只是第一步。下一步将创建定制的android平台,使其使用未删节版的android.jar,并将其添加到 Android SDK platforms文件夹中。

[安卓][转]internal(com.android.internal)和hidden(@hide)APIs简介及在应用程序中的调用方法的更多相关文章

  1. SQLite在Android程序中的使用方法,SQLite的增删查改方法

    Sqlite: 1.一款用来实现本地数据存储的轻量级数据管理工具,是众多用来实现数据库管理的工具之一. 2.Android已经将SQLite的代码功能吸收在它的系统中,我们可以直接在Android程序 ...

  2. (Android UI)Android应用程序中资源:图片、字符串、颜色、布局等

    Android系统设计采用代码和布局分离的设计模式,因此在设计Android应用程序时需要遵循该设计模式. “把非代码资源(如图片和字符串常量)和代码分离开来始终是一种很好的做法.”---<An ...

  3. Android程序中,内嵌ELF可执行文件-- Android开发C语言混合编程总结

    前言 都知道的,Android基于Linux系统,然后覆盖了一层由Java虚拟机为核心的壳系统.跟一般常见的Linux+Java系统不同的,是其中有对硬件驱动进行支持,以避开GPL开源协议限制的HAL ...

  4. com.android.internal.os.ZygoteInit$MethodAndArgsCaller 解决

    好久没写博客了,带着点小愧疚来,添上几个字: 这是今天遇到的一个bug,之前也遇到过,为了后面方便,就记下. bug提示:com.android.internal.os.ZygoteInit$Meth ...

  5. android获取com.android.internal.R

    使用class.jar, layout.jar可以直接导入com.android.internal.R 但是有个方法获取不到值mDatePicker.findViewById(com.android. ...

  6. 关于dialog引起的 java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView not attached to window manager 错误的分析

    在跑Monkey测试的时候出现了一个比较特别的问题,先来看看Log: // CRASH: com.meizu.media.painter (pid 12491) // Short Msg: java. ...

  7. where can I find source of com.android.internal.R.styleable.AlertDialog_multiChoiceItemLayout?

    I want to modify Alert dialog multi select layout. For my program I want two line multi-select item. ...

  8. Android 如何引用com.android.internal.R目录下的资源

    Android 如何引用com.android.internal.R目录下的资源 项目需求 有一个资源跟系统上的一个资源相同,想要引用它:frameworks/base/core/res/res/dr ...

  9. android在学习——activity关闭和dialog.dismiss冲突的解决(Activity has leaked window com.android.internal.policy.impl.PhoneWindow)

    当我们在退出整个程序的时候偶尔会出现这种报错:Activity has leaked window com.android.internal.policy.impl.PhoneWindow 其意思大概 ...

随机推荐

  1. 【转】java多态详解

    1.        Java中除了static和final方法外,其他所有的方法都是运行时绑定的.private方法都被隐式指定为final的,因此final的方法不会在运行时绑定.当在派生类中重写基 ...

  2. iOS 细碎知识整理

    1centerX,即x轴的中点 centery,即y轴的中点

  3. c++程序编码

    c++程序中涉及到中文字符的输入输出以及其他操作经常会出现乱码.乱码主要是由于程序的源文件编码.可执行文件编码以及程序运行环境的编码不匹配导致.比如,c++源程序文件编码为GB18030, 在源程序中 ...

  4. 慕课网:C++ & 数据结构

    课程链接:james_yuan的课程 这部分太枯燥了,如果教材难度稍大,根本就学不下去,所以就先看看通俗的视频吧. 课程目录 1.C++远征之起航篇 - C++亮点尽在其中 2.C++远征之离港篇 - ...

  5. Machine Learning - 第3周(Logistic Regression、Regularization)

    Logistic regression is a method for classifying data into discrete outcomes. For example, we might u ...

  6. JAVA多线程和并发基础面试问答

    转载: JAVA多线程和并发基础面试问答 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对 ...

  7. [你必须知道的.NET] 第八回:品味类型---值类型与引用类型(上)-内存有理

    原文地址:http://kb.cnblogs.com/page/42318/ 系列文章导航: [你必须知道的.NET] 开篇有益 [你必须知道的.NET] 第一回:恩怨情仇:is和as [你必须知道的 ...

  8. 南阳OJ----Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Given two strings A and B, whose alp ...

  9. [转]POJO中使用ThreadLocal实现Java嵌套事务

    大多嵌套事务都是通过EJB实现的,现在我们尝试实现对POJO的嵌套事务.这里我们使用了ThreadLocal的功能. 理解嵌套事务 事务是可以嵌套的.所以内层事务或外层事务可以在不影响其他事务的条件下 ...

  10. J2EE面试题

    J2EE面试题 J2EE相关基础知识 1.面向对象的特征有哪些方面  1.  抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只 ...