我想重新构建Android SDK(或者只是android.jar),以包含隐藏和内部API。
我没有找到任何关于如何进行此操作的文档或讨论。我已经设置了一个Ubuntu CyanogenMod构建环境,可以构建cm7。
现在,我了解到使用make SDK可以构建SDK,但我想构建一个包含被标记为@hide的方法和字段的SDK。这可行吗?
我想要做的是更改使用隐藏API的应用程序,并为了重新构建它,我想使用修改后的SDK。
我想重新构建Android SDK(或者只是android.jar),以包含隐藏和内部API。
我没有找到任何关于如何进行此操作的文档或讨论。我已经设置了一个Ubuntu CyanogenMod构建环境,可以构建cm7。
现在,我了解到使用make SDK可以构建SDK,但我想构建一个包含被标记为@hide的方法和字段的SDK。这可行吗?
我想要做的是更改使用隐藏API的应用程序,并为了重新构建它,我想使用修改后的SDK。
这是我使用隐藏API的常规步骤。
.iml
文件,并将所需库的<orderEntry>
放在Android SDK之前。不幸的是,这种技术不是持久的,因为一旦按下gradle-sync按钮,该文件就会被覆盖。 - waqaslam我进行了一些调查,我的结论是: 这不可能只花费很少的工作量就能完成。 阅读本答案的其余部分以获取我所发现的详细信息。
android.jar
实际上由设备中 system/frameworks/
目录中的 framework.jar
和 core.jar
的 "公共 API" 组成。 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
的工具 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 管理器中的插件,例如 Samsung 为您提供了一个额外的 API,针对 Samsung 手机的特定功能。 mkstubs
基本上与 DroidDoc 存根生成过程相同,但它不使用 @hide
注释,而是使用一个 .defs
文件来描述要包括或排除哪些包/类/字段。
然而,这与问题无关,因为 Android SDK 构建不使用 mkstubs
工具。(不幸的是。)
$(hide)
,你自己把自己搞糊涂了。 $(hide)
仅仅是用于makefile中的前缀,用于隐藏正在执行的程序的实际命令行,仅此而已,并且几乎可以在任何地方使用。它与Android SDK或源代码中的@hide
注释完全没有任何关系。 - Bjarke Freund-Hansen我们可以从Android平台重建*.jar文件。
首先,将ADB连接到您的设备。然后运行:
adb pull /system/framework/core.jar .
adb pull /system/framework/framework.jar .
core.jar
包含标准的 Java 库 (java.*
),而 framework.jar
包含 Android 库 (android.*
)。但实际上这些文件并不是 JAR 格式的,而是 DEX 格式的,因此无法直接使用。
我们可以使用工具(如dex2jar)将这些以 DEX 格式编译的 *.jars 转换成真正的 JARs:
dex2jar core.jar
dex2jar framework.jar
假设你正在使用Eclipse ADT,则使用“添加外部JAR文件...”来导入这些JAR文件。
项目 → 属性 → Java Build Path → 库 → 添加外部JAR文件
... →(从上面选择core-dex2jar.jar
和framework-dex2jar.jar
)。这将使您能够使用内部和一些Java 7 API。(据我所见,生成的APK不包含任何来自JAR文件的实际代码。)
/system/framework/core.odex
、/system/framework/framework.odex
等等。这些文件可以被反Odex化(java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core
)和重新Odex化(java -jar smali-2.0.3.jar -x -o core.dex core
),只有在此之后才能使用dex2jar core.dex
完成其工作。 - Alex Cohn你可以从这个代码库下载修改过的android.jar
,用作隐藏的API。请按照那里的说明操作。
Lollipop的流程略有不同:
从Lollipop设备获取 /system/framework/arm/boot.oat
使用 'java -jar oat2dex.jar boot boot.oat'
ps:也许您需要为'framework_classes2.dex'重复步骤4-6
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'D:\Programme\Android\android-sdk\build-tools\19.1.0\aapt.exe'' finished with non-zero exit value 1- wutzebaer
这里,Sony Ericsson的Erik Hellman解释了如何访问隐藏的Android API:
http://vimeo.com/30180393(链接似乎无法使用)。
前往DroidCon网页Day 2,向下滚动到Using Hidden APIs 10:15,就可以在那里观看。
链接正在失效!
我找到了这个:http://skillsmatter.com/podcast/os-mobile-server/hidden-api,但我不知道它能存在多久。
Android SDK中的官方API通常对大部分普通应用足够。然而,有时候开发人员需要访问内部系统服务、API和资源,而这些内容并未发布在官方API中。幸运的是,通过一些巧妙的技巧,这些API仍然可以被访问,并且在开发基于Android的新颖解决方案时经常会派上用场。在本次课程中,您将学习如何访问和使用这些隐藏和受保护的API,它们的使用限制以及如何在多个厂商设备和Android版本上以安全和可控的方式使用它们的一些技巧。观众将看到几个先进的演示,在Android中通常无法实现。期望一次相当高级的会议,带有对Android平台内部工作原理的深入见解。
Long的回答对我很有帮助,但我仍然缺少一些我需要的类,特别是android.provider.Telephony。我可以通过以下方式添加它:
提取framework.jar文件
mkdir /tmp/framework
cp framework.jar /tmp
cd /tmp/framework
jar xvf ../framework.jar
mv android classes
构建Android repo,这将创建out/target/common/obj/JAVA_LIBRARIES目录
查找缺失的类所在位置
$ 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 /tmp/framework
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 /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .
https://github.com/thoutbeckers/CollectAndroid
但是肯定需要更新任何姜饼之后的内容,主要是通过在配置文件(CollectConfig.groovy)中设置“rootdirs”的正确目录来实现。同时涉及到所有隐藏API和源码(当时也有些问题)的开发。
正如其他地方提到的那样,由于添加的访问规则,com/android/internal/**仍将在最新版本的ADT中保持隐藏状态。
我不能评论,但这基本上是对@KennyTM(https://dev59.com/wWsz5IYBdhLWcg3wcndb#13550030)出色答案的评论:
如果你在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。
@Hidden
标签,然后执行make update-api
和make SDK
来构建自己的SDK。 - dreamtale