使用内部(com.android.internal)和隐藏(@hide)API手记
内部API和隐藏API的不同
隐藏API隐藏是为了防止开发人员使用SDK中未完成或者未稳定(接口和架构方面看)的部分。比如,Bluetooth API在API Level 5(android 2.0)之前就存在,但在API Level 3和4(android 1.5和1.6)中使用@hide隐藏起来了。当该API稳定下来,google的开发人员移除@hide属性,在API Level 5中就有Bluetooth API了。还有很多东西在Level 4和5之间发生了变化。如果程序依赖于某些隐藏API,可能会在新版本的Android OS上运行出现问题。
而内部API则不计划对外开放。这是android的内部餐厅,开发人员可以视为黑盒子。这里面的东西同样可能发生改变。同样的,如果您的程序依赖于内部API,在新的Android发布后,可能遇到麻烦。
下面总结它们之间的不同:隐藏API = 正在开发中;内部API = 黑盒
1)配置SDK路径
1.1)Ubuntu:
Ctrl+Alt+T打开终端
gedit ~/.bashrc
export SDK_HOME=<SDK路径>
export PATH=$PATH:$SDK_HOME/platform-tools:$SDK_HOME/tools
source ~/.bashrc
1.2)Windows:
我的电脑->右键属性->高级->环境变量
选择系统变量新建:SDK_HOME=<SDK路径>
选择系统变量Path编辑:%SDK_HOME%\platform-tools;%SDK_HOME%\tools;<原Path>
不一定要配置,只是为了方便启动某些工具==
以下是在Windows XP下操作的~
2)AVD Manager创建模拟器并启动
以下以2.3.3平台为例了~
3)从模拟器获取framework.jar
每个模拟器或者真实设备都有一个与android.jar等价的包用于运行时。我们可以取得此jar,解出原始的.class文件,然后复制到android.jar。
adb pull /system/framework/framework.jar C:\
4)解压framework.jar获取classes.dex
5)dex2jar反编译得到原classes
classes.dex放到<dex2jar目录>内或指定绝对路径,例如为C:\classes.dex时:
进入<dex2jar目录>
dex2jar C:\classes.dex
得到classes_dex2jar.jar。
6)创建SDK定制平台
进入<SDK路径>\platforms,复制一份对应平台。2.3.3为API-10,所以如下:
复制android-10,重命名为android-10-internals。并如下修改:
1. 把上述classes_dex2jar.jar移动至android-10-internals目录
2. 解压android.jar&classes_dex2jar.jar进各自目录
3. 复制classes_dex2jar.jar解压内容全部替换android.jar解压内容
4. 重新压缩android.jar解压内容至zip,删除冗余东西,重命名回android.jar
5. 修改build.prop文件,具体如下:
ro.build.version.sdk=10 –> ro.build.version.sdk=-10
6. 修改source.properties文件,具体如下:
Platform.Version=2.3.3 –> Platform.Version=2.3.3.extended
此时重启Eclispe,即可看到我们定制的扩展SDK平台了,此时其实使用隐藏API已经足够了。
注意:重新压缩成的android.jar,看一下目录结构,不要把外层目录也加进去了。
7)定制ADT,去除ForBidden
到目前为止,ADT仍然禁止使用com.android.internals包中的类。
右键任一Android工程->Properties->左侧Java Build Path->右侧Libraries标签->Android XXX->android.jar->Access rules->Forbidden: com/android/internal/**
越过该限制规则,最简单的方式是修改ADT字节码。只需替换"com/android/internal/**”字符串为其它的字符串,比如"com/android/internax/**”。
1. 关闭Eclipse
2. 在<Eclipse目录>\plugins目录,按名称排下序,按c,找到com.android.ide.eclipse.adt_*.jar
3. 复制到外部,解压修改再打包回去,修改如下:
找出com\android\ide\eclipse\adt\internal\project\AndroidClasspathContainerInitializer.class文件
记事本打开文件,查找com/android/internal/**,替换为com/android/internal/**为com/android/internax/**。
4. 回到plugins目录,重命名原先的添加_bak,备份下,把新jar放入。
5. 打开Eclipse,再检查下^^
报错:parseSdkContent failed
com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer : Unsupported major.minor version 8241.8224
不能以记事本打开,ASNI?字节码变掉了应该==
用一些Editor以16进制方式打开搜索**,即2A 2A。把l->x,即6C->78。重弄遍,ok^^。备份是好习惯啊!
8)后记
本文源于如下网址:http://mogoweb.net/?s=%40hide;共有四部分,明细地址如下:
第1部分,介绍:http://mogoweb.net/archives/87
第2部分,定制android.jar:http://mogoweb.net/archives/92
第3部分,定制android平台:http://mogoweb.net/archives/104
第4部分,定制ADT:http://mogoweb.net/archives/117
当然,也有其他使用隐藏API的方式,不过觉着这个方式更优秀^^。
还有,AndroidManifest.xml内会是<uses-sdk android:minSdkVersion="-10" />。
补充:发现4.0模拟器内的framework.jar分出了个odex了==。
以下是反编译好的两个framework.jar(classes):
1)4.0.1(模拟器导出):framework_4.0.1.jar
2)4.0.3(源码编译得):framework_4.0.3.jar
具体如何操作,参见《Android混淆、反编译以及反破解的简单回顾》最后的补充^^。
本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/861758,如需转载请自行联系原作者