我想重建 Android SDK(或者更确切地说只是 android.jar)以包含隐藏的和内部的 API。
我找不到任何有关如何解决此问题的文档或讨论。我已经设置了能够构建 cm7 的 Ubuntu CyanogenMod 构建环境。
现在,我读到 make SDK 将构建 SDK,但我想构建一个 SDK,其中包含使用 @hide 标记为隐藏的方法和字段。这可能吗?
我想要做的是对使用隐藏 API 的应用程序进行更改,并且为了重建它,我想使用修改后的 SDK。
I want to rebuild the Android SDK (or rather only the android.jar) to include hidden and internal APIs.
I could not find any documentation or discussion doing on how to go about this. I have an Ubuntu CyanogenMod build environment already setup that is able to build cm7.
Now, I read that make SDK will build the SDK but I want to build an SDK that includes methods and fields that are marked as hidden using @hide. Is this possible?
What I want to do is make changes to an application that uses hidden API and in order to rebuild it I would like to use the modified SDK.
发布评论
评论(10)
我们可以从Android平台重建*.jar文件。
首先,将 ADB 连接到您的设备。然后运行:
core.jar
包含标准 Java 库 (java.*
),framework.jar
包含 Android 库 (>android.*
)。这尚不可用,因为实际文件是 DEX 格式,而不是 JAR 格式。我们可以使用 dex2jar 等工具将这些 DEX 格式的 *.jar 转换为真正的 JAR:
引入这些 jar
Project → Properties → Java Build Path → Libraries → Add external JARs
... → (从上面选择core-dex2jar.jar
和framework-dex2jar.jar
)。这将使您能够使用内部 API 和一些 Java 7 API。 (据我所知,生成的 APK 不包含 JAR 中的任何实际代码。)
We could reconstruct the *.jar files from the Android platform.
First, connect ADB to your device. Then run:
The
core.jar
contain the standard Java libraries (java.*
) and theframework.jar
contain the Android libraries (android.*
). This is not usable yet, as the actual files are in DEX format, not JAR format.We could convert these DEX-formatted *.jars into real JARs using tools such as dex2jar:
Then pull in these jars using "Add External JARs..." (assuming you're using Eclipse ADT)
Project → Properties → Java Build Path → Libraries → Add External JARs
... → (Choose thecore-dex2jar.jar
andframework-dex2jar.jar
from above).This will enable you to use the internal and some Java 7 APIs. (The generated APK, as far as I can see, does not contain any actual code from the JARs.)
您可以从 此下载修改后的
android.jar
以用作隐藏 API存储库。按照那里的说明进行操作。You can download the modified
android.jar
to be used as hidden APIs from this repository. Follow the instructions there.对于 Lollipop,流程略有不同:
从 lollipop 设备获取 /system/framework/arm/boot.oat
使用 'java - jar oat2dex.jar boot boot.oat'
ps: 可能您需要对“framework_classes2.dex”重复步骤 4-6
For Lollipop the flow is little different:
Get /system/framework/arm/boot.oat from lollipop device
Use 'java -jar oat2dex.jar boot boot.oat'
ps: probably you need repeat steps 4-6 for 'framework_classes2.dex'
DroidCon 2011
来自索尼爱立信的 Erik Hellman 解释了如何访问隐藏的 Android API :
http://vimeo.com/30180393
(嗯,链接似乎不起作用)。
转到DroidCon 网页第 2 天向下滚动到使用隐藏的 API 10 :15 你可以在那里观看。
链接正在消失!
我找到了这个: http://skillsmatter.com/podcast/os -mobile-server/hidden-api 我不知道,它会持续多久。
DroidCon 2011
Here Erik Hellman from Sony Ericson explains how to access the hidden Android API's:
http://vimeo.com/30180393
(Hmm link doesn't appear to work).
Goto the DroidCon webpage Day 2 scroll down to Using Hidden APIs 10:15 and you can watch it there.
Links are dieing!
I've found this one: http://skillsmatter.com/podcast/os-mobile-server/hidden-api I don't know, how long it'll be up.
尝试看看这个:
Try to look at this:
我曾经编写过一些 Groovy 脚本,用于从 http://source.android.com/ 然后编译它们,而不需要完整的工具链来编译所有 Android 源代码,包括所需的其他步骤(打包、生成资源等)。
它们可以在这里找到:
https://github.com/thoutbeckers/CollectAndroid
但是肯定的是 这将需要在 Gingerbread 之后更新任何内容,主要是通过在配置文件 (CollectConfig.groovy) 的“rootdirs”中设置正确的目录。
当时我经常使用它进行开发,并提供所有隐藏的 API 和源(当时也有问题)。
正如其他地方提到的,由于添加了访问规则,com/android/internal/** 在最新版本的 ADT 中仍将被隐藏。
I once wrote some Groovy scripts for extracting the java files from a repo checkout from http://source.android.com/ and then compiling them without the need for a full toolchain for compiling all the android sources, including the needed other steps (packaging, generating resources etc).
They can be found here:
https://github.com/thoutbeckers/CollectAndroid
But for sure this will need updating for anything after Gingerbread, mostly by setting the correct directories in "rootdirs" in the config file (CollectConfig.groovy).
At the time I regularly used this for development with all of the hidden API and sources (also problematic at the time) available.
As mentioned elsewhere com/android/internal/** will still be hidden in recent versions of ADT due to the access rule aded.
Long的答案对我有用,但我仍然缺少一些我需要的课程,特别是 android.provider.Telephony。我可以像这样添加它:
提取framework.jar文件
构建Android存储库,这将创建out/target/common/obj/JAVA_LIBRARIES目录
查找缺少的类的位置
添加新类并重建框架 JAR 文件
或者您可以偷懒,将所有类包含到一个巨大的 jar 文件中:
Long's answer worked for me, but I was still missing some classes I needed, in particular android.provider.Telephony. I was able to add it like this:
Extract the framework.jar file
Build the Android repo, which will create the out/target/common/obj/JAVA_LIBRARIES directory
Find where the missing classes are
Add the new classes and rebuild the framework JAR file
Or you can just be lazy and include all of the classes into one giant jar file:
我无法发表评论,但这基本上是对 @KennyTM 的评论 (https://stackoverflow.com/a/13550030/2923406) 优秀的答案:
如果您发现自己在 Eclipse 中出现以下错误:(
即 android.internal.* 不可用)
那么一种可能的解决方案是应用/system/framework/framework2.jar 的方法相同。使用 SDK19 的 Android 模拟器我有这个额外的 jar。在我的 HTC One 上甚至还有一个 Framework3.jar。
I can't comment but this is basically a comment to @KennyTM's (https://stackoverflow.com/a/13550030/2923406) excellent answer:
If you find yourself with the following error in Eclipse:
(that is, android.internal.* is not available)
Then one possible solution is to apply the same method for /system/framework/framework2.jar. Using the Android Emulator for SDK19 I have this extra jar. On my HTC One there is even a framework3.jar.
这就是我使用隐藏 api 时经常做的事情。
This is what I always do to use hidden api.
我对此进行了一些调查,我的结论很简单:如果没有大量工作,这是不可能完成的。阅读本答案的其余部分,了解我发现的详细信息。
android.jar
实际上由framework.jar
和core.jar
的“公共 api”组成,可以在system/ 中找到设备上的框架/
。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
中的源代码构建的,它本身是由工具 DroidDoc 生成的位于build/tools/droiddoc
中。DroidDoc 是生成实际 Android SDK 文档的工具(可能改编自 javadoc,或使用 javadoc)。作为副作用,可能是因为它已经解析了所有 javadoc,它还生成了 android 存根,然后这些存根被编译到在 SDK 中分发的
android.jar
中。因此,要包含隐藏的内容,如果您只想包含特定部分,只需删除
@hide
注释并重建 SDK 即可。但是,如果您想包含所有隐藏部分,事情就会变得更加复杂。您可以修改DroidDoc(相关源位于
build/tools/droiddoc/src/Stubs.java
中),这样就不会检测到任何隐藏内容。这是非常简单的,我已经尝试过了,但是随后生成的存根根本无法编译。我现在的结论是,这根本不可行。如果删除 DroidDoc 中检测隐藏注释的部分,生成的存根根本无法编译,并且需要大量工作才能正确编译。
所以我对你的问题的回答是:不,如果不做大量工作,这是不可能完成的。抱歉。
关于
mkstubs
工具的旁注。mkstubs
在您构建 SDK 插件时使用,即您可以在供应商的 Android SDK 管理器中找到的插件,例如三星为您提供了针对特定内容的附加 API三星手机。mkstubs
与 DroidDoc 存根生成过程大致相同,但它不使用@hide
注释,它使用.defs
文件描述要包含或排除在 SDK 插件中的包/类/字段。然而,这与问题无关,因为 Android SDK 构建不使用
mkstubs
工具。 (很遗憾。)I have done some investigating into this, and my conclusion is simply: This cannot be done without quite a bit of work. Read the rest of this answer for details on what I have found.
android.jar
is actually comprised of the "public api" offramework.jar
andcore.jar
which is found insystem/frameworks/
on the device.android.jar
is a kind of what I would call Java library header, all implementation in the actual byte code are just athrow new RuntimeException("stub");
, this allows you to build againstandroid.jar
(e.g. in Eclipse), but execution has to be performed on a device or emulator.The public API of the Android SDK is defined by classes/methods/fields that are not prefixed with the
@{hide}
javadoc annotation. I.e. everything that is not annotated is included in the SDK.android.jar
is built from the sources located inout/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates
which itself is generated by the tool DroidDoc located inbuild/tools/droiddoc
.DroidDoc is the tool (probably adapted from javadoc, or using javadoc) that generate the actual Android SDK documentation. As a side-effect, and probably because it is already parsing all the javadoc, it also spews out the android stubs which are then compiled into the
android.jar
which is distributed in the SDK.So to include the stuff that is hidden you could, if you only want to include specific parts, just remove the
@hide
annotation and rebuild the SDK.However if you want to include all the hidden parts things get a lot more complicated. You can modify DroidDoc (the relevant source is in
build/tools/droiddoc/src/Stubs.java
) such that nothing is detected as hidden. This is quite trivial and I have tried this, however the stubs that is then generated does not compile at all.My conclusion by now is that this is simply not feasible. The stubs generated if you remove the part of DroidDoc that detect hidden annotations, is simply not compilable, and would require quite a bit of work to compile correctly.
So my answer to your questions is: No, this cannot be done, without doing a lot of work. Sorry.
A side note about the
mkstubs
tool.mkstubs
are used when you build a SDK addon, i.e. the addons you can find in the Android SDK manager from vendors, e.g. Samsung providing you with an additional API for stuff specific to Samsung phones.mkstubs
does much the same as the DroidDoc stubs generation process, however it does not use@hide
annotations, it uses a.defs
file describing which packages/classes/fields to include or exclude from your SDK addon.However this is all irrelevant to the question, as the Android SDK build does not use the
mkstubs
tool. (Unfortunately.)