5

Android 构建过程为 android.jar 中的每个类生成(?)Java 存根,并将它们存储在以下目录中:

./out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/

例如,java/lang/上述目录的子目录包含java.lang.*类对应的.java文件,而`android/app/'子目录包含android.app.*类对应的.java文件。这些 .java 文件不包含实际代码,而只是带有虚拟主体的签名。

我假设这些 .java 文件是使用工具从实际源代码生成的。我的问题是,这个工具是什么,它是否可以在 Android 构建过程之外使用?

我想使用该工具为非 Android Java 类生成存根。

4

1 回答 1

11

这里的“存根”是运行 javadoc 工具生成的框架 API 存根。

在大多数情况下,当我们谈到Android中的stub文件时,我们指的是aidl工具生成的java文件。例如,请参阅如何在 android 中生成存根?- 堆栈溢出

特别是,Android 构建系统包含一个名为 makefile droiddoc.mk,可用于生成文档、java API 存根和 API xml 文件,它实际上调用 javadoc。
droiddoc.mkbuild/core。其中build/core/config.mk有一个名为的变量BUILD_DROIDDOC,以便更容易包含droiddoc.mk.

看一下droiddoc.mk,它调用了javadoc:

javadoc \
            \@$(PRIVATE_SRC_LIST_FILE) \
            -J-Xmx1280m \
            $(PRIVATE_PROFILING_OPTIONS) \
            -quiet \
            -doclet com.google.doclava.Doclava \
            -docletpath $(PRIVATE_DOCLETPATH) \
            -templatedir $(PRIVATE_CUSTOM_TEMPLATE_DIR) \
            $(PRIVATE_DROIDDOC_HTML_DIR) \
            $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
            $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
            -sourcepath $(PRIVATE_SOURCE_PATH)$(addprefix :,$(PRIVATE_CLASSPATH)) \
            -d $(PRIVATE_OUT_DIR) \
            $(PRIVATE_CURRENT_BUILD) $(PRIVATE_CURRENT_TIME) \
            $(PRIVATE_DROIDDOC_OPTIONS) \
    && touch -f $@ 

存根什么都没有,对吧?不用担心,注意有一个PRIVATE_DROIDDOC_OPTIONS变量,并且

PRIVATE_DROIDDOC_OPTIONS := $(LOCAL_DROIDDOC_OPTIONS)

AOSP 中的许多 Android.mk 文件,例如framework/base/Android.mk,都包含include $(BUILD_DROIDDOC)生成文档。中framework/base/Android.mk,有一段代码:

LOCAL_DROIDDOC_OPTIONS:=\
                $(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
                -stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_stubs_current_intermediates/src \
                -api $(INTERNAL_PLATFORM_API_FILE) \
                -nodocs

LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk

LOCAL_UNINSTALLABLE_MODULE := true

include $(BUILD_DROIDDOC)

LOCAL_DROIDDOC_OPTIONS包含一个-stubs选项。它最终会放入 droiddoc.mk 使用的 javadoc 命令中。

但是,我们可能会注意到 javadoc 不包含任何选项,例如-stubs. 关键是您可以使用 doclet 自定义 Javadoc 工具输出的内容和格式。Javadoc 工具有一个默认的“内置” doclet,称为标准 doclet,它生成 HTML 格式的 API 文档。您可以修改或子类化标准 doclet,或编写自己的 doclet 以生成 HTML、XML、MIF、RTF 或您想要的任何输出格式。

我们可以使用该-doclet选项来指定我们自定义的 doclet。droiddoc.mk 中的 javadoc 命令使用-doclet com.google.doclava.Doclava. 该 doclet 接收该-stubs选项。

查看下的 Doclava 实现external/doclava/src/com/google/doclava/Doclava.java

  else if (a[0].equals("-stubs")) {
    stubsDir = a[1];
  } else if (a[0].equals("-stubpackages")) {
    stubPackages = new HashSet<String>();
    for (String pkg : a[1].split(":")) {
      stubPackages.add(pkg);
    }
  }

它接收 -stubs 选项。以下是它处理 stubsDir 的方式。

// Stubs
if (stubsDir != null || apiFile != null || proguardFile != null) {
  Stubs.writeStubsAndApi(stubsDir, apiFile, proguardFile, stubPackages);
}

并跟踪 stub 文件的实现Stubs.writeStubsAndApi,你可以看到为什么存根文件中的内容是这样的。

您甚至可以编写自己的 java 文件并生成您的存根,就像build/tools/droiddoc/test.

于 2013-04-18T11:15:05.913 回答