我想重建Android SDK(或更确切地说,仅是android.jar)以包括隐藏的和内部的API。
我找不到有关如何执行此操作的任何文档或讨论。我已经安装了一个能够构建cm7的Ubuntu CyanogenMod构建环境。
现在,我读到make SDK将构建SDK,但我想构建一个SDK,其中包含使用@hide标记为隐藏的方法和字段。这可能吗?
我想要做的是对使用隐藏API的应用程序进行更改,为了重建它,我想使用修改后的SDK。
我想重建Android SDK(或更确切地说,仅是android.jar)以包括隐藏的和内部的API。
我找不到有关如何执行此操作的任何文档或讨论。我已经安装了一个能够构建cm7的Ubuntu CyanogenMod构建环境。
现在,我读到make SDK将构建SDK,但我想构建一个SDK,其中包含使用@hide标记为隐藏的方法和字段。这可能吗?
我想要做的是对使用隐藏API的应用程序进行更改,为了重建它,我想使用修改后的SDK。
@Hidden
要访问的API的标签,然后执行make update-api
并make SDK
构建自己的SDK。
Answers:
这就是我始终使用隐藏api所做的事情。
.iml
文件,并将所需的lib放在Android SDK<orderEntry>
之前。不幸的是,该技术不是持久性的,因为一旦按下gradle-sync按钮,文件将被覆盖。
我已经对此进行了一些调查,而我的结论很简单:没有大量工作就无法完成。阅读此答案的其余部分,以详细了解我所发现的内容。
android.jar
实际上由“公共API”的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
本身由工具生成DroidDoc位于build/tools/droiddoc
。
DroidDoc是用于生成实际Android SDK文档的工具(可能是从javadoc改编而成,或使用javadoc编写的)。作为副作用,可能是因为它已经解析了所有javadoc,所以它还会喷出android存根,然后将android.jar
其编译为在SDK中分发的。
因此,要包含隐藏的内容,如果只想包含特定部分,则可以删除@hide
注释并重新构建SDK。
但是,如果要包括所有隐藏部分,事情会变得复杂得多。您可以修改DroidDoc(相关的源代码位于中build/tools/droiddoc/src/Stubs.java
),以使没有任何东西被检测为隐藏。这非常琐碎,我已经尝试过了,但是随后生成的存根根本无法编译。
我现在的结论是,这根本不可行。如果删除DroidDoc中检测隐藏注释的部分,则生成的存根根本无法编译,并且需要大量工作才能正确编译。
因此,我对您的问题的回答是:不,如果不做很多工作就无法完成。抱歉。
有关该mkstubs
工具的旁注。mkstubs
在构建SDK插件时使用,即您可以在Android SDK管理器中从供应商处找到的插件,例如Samsung为您提供了针对Samsung手机特定内容的附加API。mkstubs
与DroidDoc存根生成过程大致相同,但是它不使用@hide
注释,它使用一个.defs
文件来描述要从SDK插件中包含或排除哪些程序包/类/字段。
然而,这一切无关的问题,如在Android SDK构建并不能使用该mkstubs
工具。(不幸。)
@hide
注释,它“只是”使用一个.defs
文件来描述插件的API中将包含哪些包/类/字段。
$(hide)
,您感到困惑。$(hide)
只是makefile中的前缀,以隐藏正在执行的程序的实际命令行,仅此而已,并且它几乎在任何地方都可以使用。它与Android SDK或@hide
源代码中的注释无关。
我们可以从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 ...”拉入这些jar(假设您正在使用Eclipse ADT)
Project → Properties → Java Build Path → Libraries → Add External JARs
...→(从上方选择core-dex2jar.jar
和framework-dex2jar.jar
)。这将使您能够使用内部和某些Java 7 API。(据我所知,生成的APK不包含JAR中的任何实际代码。)
/system/framework/core.odex
,,/system/framework/framework.odex
可能还有更多。可以对它们进行脱氧(java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core
)和脱氧((java -jar smali-2.0.3.jar -x -o core.dex core
))操作,然后再进行dex2jar core.dex
工作。
对于棒棒糖,流程几乎没有什么不同:
从棒棒糖设备获取/system/framework/arm/boot.oat
使用'java -jar oat2dex.jar boot boot.oat'
ps:可能您需要为“ framework_classes2.dex”重复步骤4-6
索尼爱立信的Erik Hellman在这里说明了如何访问隐藏的Android API:
http://vimeo.com/30180393(Hmm 链接似乎不起作用)。
转到DroidCon网页的第2天,向下滚动到Using Hidden APIs 10:15,您可以在那里观看。
链接消失了!
我找到了这个:http : //skillsmatter.com/podcast/os-mobile-server/hidden-api dunno它将持续多长时间
Android SDK中的官方API通常对于大多数普通应用程序就足够了。但是,有时在某些情况下,开发人员需要访问未在官方API中发布的内部系统服务,API和资源。幸运的是,这些API仍可以通过一些巧妙的技巧获得,并且在基于Android的基础上开发新的创新解决方案时通常非常有用。在本课程中,您将学习如何访问和使用这些隐藏和受保护的API,它们的使用限制以及如何在多个供应商的设备和Android版本之间以安全和可控制的方式使用它们的一些技巧。观众将看到几个通常无法使用Android进行的高级演示。期待一个相当高级的会议,其中包含有关Android平台内部知识的大量见解。
您可以android.jar
从此存储库下载修改后的用作隐藏API 。按照那里的说明进行操作。
尝试看看这个:
这些文章的最终目标是在不使用反射的情况下为开发人员提供内部和隐藏API的功能。如果您完成了以下几部分中描述的所有步骤,您将能够使用内部和隐藏API,就像它们是公共开放API一样。无需反思。
但是,如果您使用的是这些非公共API,则应意识到您的应用程序存在很大的风险。基本上,我们无法保证在下次更新Android OS时不会破坏API。甚至不能保证来自不同供应商的设备之间的行为一致。您完全是一个人。
您可能要遵循三种情况:
- 启用内部和隐藏API(方案A)
- 仅启用隐藏的API(方案B)
- 仅启用 内部API(方案C)
方案A是B和C的总和。方案B是最简单的方案(不需要修改Eclipse ADT插件)。
我曾经写过一些Groovy脚本,用于从http://source.android.com/的回购结帐中提取Java文件,然后进行编译,而无需使用完整的工具链来编译所有android源代码,包括所需的其他步骤(包装,产生资源等)。
它们可以在这里找到:
https://github.com/thoutbeckers/CollectAndroid
但是可以肯定这需要在Gingerbread之后进行任何更新,主要是通过在配置文件(CollectConfig.groovy)的“ rootdirs”中设置正确的目录。
当时,我经常使用它进行开发,并提供所有隐藏的API和源(当时也有问题)。
如其他地方所述,由于访问规则的加入,com / android / internal / **仍会在ADT的最新版本中隐藏。
Long的答案对我有用,但是我仍然缺少一些我需要的类,特别是android.provider.Telephony。我能够像这样添加它:
提取framework.jar文件
mkdir /tmp/framework
cp framework.jar /tmp
cd /tmp/framework
jar xvf ../framework.jar
mv android classes
构建Android存储库,这将创建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 .
我无法发表评论,但这基本上是对@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。