如何构建具有隐藏和内部API的Android SDK?

时间:2011-10-25 10:55:13

标签: android android-sdk-2.3 android-source

我想重建Android SDK(或者更确切地说只是android.jar)以包含隐藏和内部API。

我找不到任何关于如何解决这个问题的文档或讨论。我已经设置了一个能够构建cm7的Ubuntu CyanogenMod构建环境。

现在,我读到make SDK将构建SDK,但我想构建一个SDK,其中包含使用@hide标记为隐藏的方法和字段。这可能吗?

我想要做的是更改使用隐藏API的应用程序,为了重建它,我想使用修改后的SDK。

10 个答案:

答案 0 :(得分:62)

这是我一直使用隐藏的api。

  1. https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong
  2. 构建仓库或下载罐子
  3. 复制出/ t​​arget / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar(最好将其重命名为framework_all.jar)
  4. 配置您的项目构建路径 - > libraries - >添加这个外部罐子。在Order and Export中,将其向上移动并在android.jar
  5. 之前

答案 1 :(得分:39)

我已经对此进行了一些调查,我的结论很简单:如果没有相当多的工作,这是不可能完成的。请阅读本答案的其余部分,了解我所找到的详细信息。< / p>


android.jar实际上由&#34; public api&#34;组成。在framework.jar设备上找到的core.jarsystem/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.jarframework-dex2jar.jar。)

这将使您能够使用内部和一些Java 7 API。 (据我所知,生成的APK不包含来自JAR的任何实际代码。)

答案 3 :(得分:16)

对于棒棒糖来说,流量差别不大:

  1. 从棒棒糖设备获取/system/framework/arm/boot.oat

  2. 使用'java -jar oat2dex.jar boot boot.oat'

  3. 您将获得两个文件夹:dex和odex。转到dex并制作'java -jar dex2jar.jar framework.dex'
  4. 将生成的framework.jar重命名为.zip,提取并查找所需的类
  5. 转到[sdk_path] / platforms / [target_platform]并解压缩android.jar(首先将其重命名为zip)。
  6. 将提取的框架中的文件复制到解压缩的android.jar中。然后压缩到zip并重命名为.jar:)
  7. ps:可能你需要为'framework_classes2.dex'重复步骤4-6

答案 4 :(得分:15)

DroidCon 2011

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。甚至不保证来自不同供应商的设备之间的一致行为。你完全靠自己。

     

您可能想要遵循三种方案:

     
      
  1. 同时启用内部隐藏 API(方案A)
  2.   
  3. 仅启用隐藏 API(方案B)
  4.   
  5. 仅启用内部 API(方案C)
  6.         

    场景A是B和C的总和。场景B是最简单的场景(不需要修改eclipse ADT插件)。

         

    情景A :阅读部分12345

         

    情景B :阅读部分1235

         

    情景C :阅读部分12345

答案 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。我能够像这样添加它:

  1. 查找班级的位置

    $ 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
    
  2. 添加新类并重建框架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 .
    
  3. 或者你可以只是懒惰并将所有类包含在一个巨大的jar文件中:

    cd /path/to/temp/folder
    cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
    cd classes
    jar cvf ../framework.jar .