android 访问隐藏API

最简单的方法是:

在android-sdk-linux_x86/platforms/android-10/data/layoutlib.jar中包含了source中internal的api,在eclipse中导入这个jar包就可以使用internal的api了。
导入方法:
1. Right-click the project in Eclipse and select "Build Path -> Add Libraries...".
2. Select User Library from the list and click Next.
3. Click the "User Libraries..." button.
4. Click "New..." in the User Libraries dialog.
5. Give the user library a name and select the System library checkbox and click OK.
6. Highlight the newly added user library in the list and click the "Add JARs..." button and add the desired jar files.
7. Click OK on the User Libraries dialog.
8. Make sure the new user library is checked in the Add Library dialog and


或者使用以下方法:

Android有两种类型的API是不能经由SDK访问的。

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

Hidden API 例子

你可以查看一下android的源码,并能找到一些变量、函数和类等,都被@hide属性标记了。

下面的例子就是在WifiManager(API 10源码)中隐藏的变量。

clip_image002

另一个例子是在WifiManager(API 10源码)中隐藏了setWifiApEnabled函数。

clip_image004

因此,只要你看到@hide属性,那你看到的就是hidden API。

Internal和hidden 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发生变化,从而令你失望。

总结一下区别:

Hidden API = 进行中的工作;

Internal API = 黑盒;

Internal和hidden 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)。

clip_image006

clip_image008

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

不通过反射使用internal和hidden 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


我解释了为什么我们不通过反射就会很难使用internal和hidden API。这是因为android.jar中就没包含这些API,因此,没人能够在编译时引用这些类。

这篇文章将描述如何还原最初的android.jar。这将允许我们像使用公开的API那样使用internal和hidden API。

如何得到原版android.jar?

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

1) Android是一个开源工程。我们可以下载源码并搭建编译环境,这样它就不能移除那些internal和hidden的类了。这个办法比较困难;

2) 每个模拟器或真机在运行时都会有一个等同android.jar的东西。我们可以从这里拿到jar文件,提取出原始的.class文件,并拷贝到Android SDK的android.jar中。

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

从设备上获取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并解压到独立的文件夹中,看起来是这个样子的:

clip_image002

classes.dex正是我们需要的。

创建framework-classes.zip

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

dev2jar classes.dex

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

clip_image004

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

创建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。

步骤总结

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

打完收功。

总结

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



我已经展示了如何创建一个包含所有internal和hidden API的original-android.jar。

接下来的工作就是要修改已经存在的Android平台(SDK_DIR/platforms/platform-X/android.jar,X表示API等级)。你可以直接使用Part2中创建的original-android.jar替换android.jar。但这样的话,你的所有工程都将直接使用internal和hidden API而没有任何限制。这不够方便,因为在多数的工程中你不希望这样。甚至,你可能更希望禁止这些API(ADT/android.jar的默认行为)。但对于一些特定的工程,你希望能够使用这些internal和hidden API。

为了达到这样的灵活性,你需要创建一个新的自定义的Android平台。当不需要访问internal和hidden API时,你只需使用原有的Android平台。当你使用这些API时,你使用自定义的Android平台。

Android SDK文件夹结构

让我们看一下Android SDK树是如何组织的:

clip_image002

我们需要“platforms”文件夹。看一下里面:

clip_image004

这里列出了支持的Android平台。

现在,我们看一下它是如何与Eclipse设定关联的。选择你的工程,右击–> Properties –> Android。你将会看到一组支持的Android平台(与…/platforms/folder相似)。下面是截图:

clip_image006

创建新的平台

为了创建一个新的平台,我们需要拷贝android-9文件夹 -> android-9-internals。让我们做一些修正:

1. 删除其中的android.jar

2. 拷贝original-android.jar,并改名为android.jar

3. 修改build.prop文件:

ro.build.version.sdk=9 -> ro.build.version.sdk=-9

ro.build.version.release=2.3 -> ro.build.version.release=2.3.extended

重启Eclipse。并确认你能看到新的平台。下面是我所看到的:

clip_image008

为什么我选择API等级为-9?这是因为它必须是一个数字,而且它不能是9(或者其它已经存在的API等级)。否则,你自定义的平台将不能被使用(它在列表里可见,但选中后也不能正常工作,编译时仍然使用相应API等级的原始平台)。

下面是引用类库的截图(当前工程选中了自定义的平台):

clip_image010

总结

在上一篇中,我已经告诉你如何创建一个未删节版的android.jar。在这一篇中,我向你展示了如何创建一个自定义的Android平台,并在其中使用original-android.jar。这对于hidden API来说已经足够了。但对于internal API来说,还需要另一步。这是因为ADT仍然不允许使用com.android.internal包中的类(参见上图中的“forbidden”访问规则)。下一节我将向你展示如何定制ADT来允许使用internal包中的类。

============华丽的分割线=============

在实际的操作过程中,我创建的自定义的android.jar(API 10)不能被Eclipse成功加载,会出现以下的错误框,如同网站上其它人操作的结果一样,期待解决方案。

clip_image012

不过,作者提供了可用的自定义的android.jar,如果不想自己尝试的话,可以直接从网站下载,地址将在Part5中给出,稍等。


为了能够使用Internal和Hidden API,你需要:

1. 创建自定义的original-android.jar,包含所有的.class文件

2. 创建自定义的Android平台来使用original-android.jar

3. 修改ADT插件,允许使用com.android.internal包(只为Internal API)

4. 创建新的工程,引用自定义的Android平台(本文中的例子)

在本文中,我将向你们展示如何使用那些Internal和Hidden API。

此外,在本文的结尾,我列出了一些自定义的Android平台,它们都包含Internal和Hidden API。我附带了它们,是为了可能你不想花太多时间在这方面,但又想快速的尝试什么。

例子

创建一个新工程,选择2.3.extender平台:

clip_image002

下面是代码:

clip_image004

这个代码使用了Internal API(PowerProfile)和Hidden API(isWifiApEnabled)。我不用使用反射就能编译并运行这些代码。

自定义平台

下面有些平台,是我为自己创建的。只用拷贝它们到SDK_DIR\platforms文件夹下。这只是让Hidden API可用。对于Internal API,你需要修改你的ADT插件。

API 3:http://www.megaupload.com/?d=S1F2MKYZ

API 4:http://www.megaupload.com/?d=VUCTRI3Y

API 7:http://www.megaupload.com/?d=7ITNILBK

API 8:http://www.megaupload.com/?d=EXT5FKKT

API 9:http://www.megaupload.com/?d=EXT5FKKT

API 10:http://www.megaupload.com/?d=FCV78A9M

==============华丽的分割线=============

我尝试了其中的几个自定义平台,发现,internal 和hidden API真的是可用了,但也有一些意外的问题,如AlertDialog.Builder(Context context)居然说Context参数是多余的。。

没花时间去研究为什么会这样,如果哪位童鞋知道原因,告诉我哈~~

来源:http://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值