转自: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. 转!sqlServer2000 表连接查询

    在查询多个表时,我们经常会用“连接查询”.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据 ...

  2. mac中openfire启动失败的解决方式

    不知为何,几次出现这个问题了 解决方法:使用终端命令 1:sudo chmod -R 777 /usr/local/openfire/bin 2:cd /usr/local/openfire/bin ...

  3. jstree级联查找树

    <script > obj=$.jstree.reference($('#plugins4')); function PP(obj,e,filename){ if (obj.get_par ...

  4. phalcon: router规则与解析,已经生成router的链接地址

    本人采用的是假分模块(目录),通过命名空间来进行模块分组的,非官方分组,所以在router是都会加上 namespace 信息,你也可适当的参考: 前提: /** * 注册命名空间 */ $loade ...

  5. wifi adb 调试手机

    首先手机,PC都连上WIFI, 如果可以用USB操作,在PC端,输入ping 手机的ip 地址,看看是否成功, 在PC端输入下面命令adb tcpip 5555adb connect 192.168. ...

  6. Selenium Grid Configuration

    Start Hub and Node with Json config 1. Start Hub with json config file title HubWebDriver java -jar ...

  7. Unity5 新功能解析--GI(全局光)

    http://blog.csdn.net/leonwei/article/details/48009059 Unity5带来的最大的改变就是全新的GI,在烘焙引擎上抛弃了4的beast,使用了虚幻采用 ...

  8. android AutoCompleteTextView和Spinner选中项加亮

    package com.example.spinnerexample; import java.util.ArrayList; import java.util.List; import androi ...

  9. Lecture Notes: Macros

    原论文链接失效,特在这里保存一份 http://www.apl.jhu.edu/~hall/Lisp-Notes/Macros.html Lisp functions take Lisp values ...

  10. javascript图片切换

    JavaScript 图片滑动切换效果 作者:cloudgamer 时间: 2009-09-25 文档类型:原创 来自:蓝色理想 第 1 页 JavaScript 图片滑动切换效果 [1] 第 2 页 ...