我想重建Android SDK(或者更确切地说只是android.jar)以包含隐藏和内部API。
我找不到任何关于如何解决这个问题的文档或讨论。我已经设置了一个能够构建cm7的Ubuntu CyanogenMod构建环境。
现在,我读到make SDK将构建SDK,但我想构建一个SDK,其中包含使用@hide标记为隐藏的方法和字段。这可能吗?
我想要做的是更改使用隐藏API的应用程序,为了重建它,我想使用修改后的SDK。
答案 0 :(得分:62)
这是我一直使用隐藏的api。
答案 1 :(得分:39)
我已经对此进行了一些调查,我的结论很简单:如果没有相当多的工作,这是不可能完成的。请阅读本答案的其余部分,了解我所找到的详细信息。< / p>
android.jar
实际上由&#34; public api&#34;组成。在framework.jar
设备上找到的core.jar
和system/frameworks/
。 android.jar
是我称之为Java库头的一种,实际字节代码中的所有实现都只是throw new RuntimeException("stub");
,这允许你构建android.jar
(例如在Eclipse中),但必须在设备或模拟器上执行。
Android SDK的公共API由不前缀为@{hide}
javadoc注释的类/方法/字段定义。即所有未注释的内容都包含在SDK中。
android.jar
是根据out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates
中的来源构建的,build/tools/droiddoc
本身由位于android.jar
的工具 DroidDoc 生成。
DroidDoc 是生成实际Android SDK文档的工具(可能改编自javadoc,或使用javadoc)。作为一个副作用,可能因为它已经解析了所有的javadoc,它也会喷出android存根,然后编译成在SDK中分发的@hide
。
因此,要包含您可能隐藏的内容,如果您只想包含特定部分,只需删除build/tools/droiddoc/src/Stubs.java
注释并重建SDK。
但是,如果你想要包含所有隐藏的部分,事情会变得复杂得多。您可以修改 DroidDoc (相关来源位于mkstubs
),以便不会将任何内容检测为隐藏。这是非常简单的,我尝试过这个,但是生成的存根根本不会编译。
我现在的结论是,这根本不可行。如果删除检测隐藏注释的DroidDoc部分而生成的存根,则根本无法编译,并且需要相当多的工作才能正确编译。
所以我对你的问题的回答是:不,如果不做大量的工作,就无法做到这一点。遗憾。强>
关于mkstubs
工具的附注。构建 SDK插件时会使用mkstubs
,即您可以在供应商的Android SDK管理器中找到的插件,例如三星为您提供针对三星手机特定内容的附加API。 @hide
与DroidDoc存根生成过程大致相同,但它不使用.defs
注释,它使用mkstubs
文件描述要包含或排除哪些包/类/字段SDK插件。
然而,这与问题无关,因为Android SDK构建不使用{{1}}工具。 (可惜。)
答案 2 :(得分:29)
我们可以从Android平台重建* .jar文件。
首先,将ADB连接到您的设备。然后运行:
adb pull /system/framework/core.jar .
adb pull /system/framework/framework.jar .
core.jar
包含标准Java库(java.*
),framework.jar
包含Android库(android.*
)。这还不可用,因为实际文件是DEX格式,而不是JAR格式。
我们可以使用dex2jar等工具将这些DEX格式的* .jars转换为真正的JAR:
dex2jar core.jar
dex2jar framework.jar
然后使用“添加外部JAR ...”(假设您正在使用Eclipse ADT)拉入这些罐子
Project → Properties → Java Build Path → Libraries → Add External JARs
...→(从上方选择core-dex2jar.jar
和framework-dex2jar.jar
。)这将使您能够使用内部和一些Java 7 API。 (据我所知,生成的APK不包含来自JAR的任何实际代码。)
答案 3 :(得分:16)
对于棒棒糖来说,流量差别不大:
从棒棒糖设备获取/system/framework/arm/boot.oat
使用'java -jar oat2dex.jar boot boot.oat'
ps:可能你需要为'framework_classes2.dex'重复步骤4-6
答案 4 :(得分:15)
Sony Ericson的Erik Hellman解释了如何访问隐藏的Android API:
http://vimeo.com/30180393 (嗯链接似乎不起作用)。
转到DroidCon webpage Day 2向下滚动至使用隐藏的API 10:15 ,您可以在那里观看。
链接正在消亡!
我找到了这个:http://skillsmatter.com/podcast/os-mobile-server/hidden-api不知道它会多长时间
Android SDK中的官方API通常足以满足大多数普通应用程序的需求。但是,有时开发人员需要访问未在官方API中发布的内部系统服务,API和资源。幸运的是,这些API仍然可以通过一些巧妙的技巧获得,并且在Android上开发新的创新解决方案时通常很有用。在本课程中,您将学习如何访问和使用这些隐藏和受保护的API,它们的使用限制以及如何在多个供应商设备和Android版本中以安全和控制的方式使用它们的一些技巧。观众将看到一些您通常无法使用Android进行的高级演示。期待一个相当高级的会议,在Android平台的内部有很多见解。
答案 5 :(得分:12)
尝试查看this:
这些文章的最终目标是为开发人员提供内部和隐藏API的强大功能,而无需使用反射。如果您完成了下面几个部分中描述的所有步骤,您将能够使用内部和隐藏 API,就像它们是公共开放API一样。没有必要反思。
但是如果您使用这些非公共API,那么您应该知道您的应用程序存在很大风险。基本上无法保证下次更新Android操作系统时不会破坏API。甚至不保证来自不同供应商的设备之间的一致行为。你完全靠自己。
您可能想要遵循三种方案:
答案 6 :(得分:11)
您可以从this repository下载修改后的android.jar
以用作隐藏API。按照那里的说明进行操作。
答案 7 :(得分:1)
我曾经写过一些Groovy脚本,用于从http://source.android.com/的repo checkout中提取java文件,然后编译它们,而不需要一个完整的工具链来编译所有的android源码,包括所需的其他步骤(打包,产生资源等)。
他们可以在这里找到:
https://github.com/thoutbeckers/CollectAndroid
但肯定这需要在Gingerbread之后更新任何内容,主要是通过在&#34; rootdirs&#34;中设置正确的目录。在配置文件中(CollectConfig.groovy)。
当时我经常使用它来开发所有隐藏的API和源(当时也有问题)。
正如其他地方所提到的,由于访问规则的原因,com / android / internal / **仍将隐藏在最新版本的ADT中。
答案 8 :(得分:0)
我无法发表评论,但这基本上是对@ KennyTM(https://stackoverflow.com/a/13550030/2923406)优秀答案的评论:
如果您在Eclipse中发现以下错误:
The type com.android.internal.util.Predicate cannot be resolved. It is indirectly referenced from required .class files
(即android.internal。*不可用)
然后一种可能的解决方案是对/system/framework/framework2.jar应用相同的方法。使用适用于SDK19的Android模拟器我有这个额外的jar。在我的HTC One上甚至还有一个framework3.jar。
答案 9 :(得分:0)
Long's answer为我工作,但我仍然缺少一些我需要的课程,特别是android.provider.Telephony。我能够像这样添加它:
查找班级的位置
$ cd /path/to/out/target/common/obj/JAVA_LIBRARIES
$ find . | grep "/Telephony.class"
./telephony-common_intermediates/classes/android/provider/Telephony.class
./android_stubs_current_intermediates/classes/android/provider/Telephony.class
添加新类并重建框架JAR文件
cd /path/to/temp/folder
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes .
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes .
cd classes
jar cvf ../framework.jar .
或者你可以只是懒惰并将所有类包含在一个巨大的jar文件中:
cd /path/to/temp/folder
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .