【问题标题】:Add one android project as a library in AOSP App在 AOSP App 中添加一个 android 项目作为库
【发布时间】:2013-08-22 04:20:14
【问题描述】:

我想通过从另一个 Android 应用程序启动一个活动来将一些功能添加到浏览器应用程序中。当我制作主项目时,它给了我package does not exist。请注意,我看到 AndroidLib 已成功构建到 out/target/product/generic/data/app/AndroidLib.apk

这里有两个 android.mk 文件: AndroidLib(一个普通的Android App)

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_STATIC_JAVA_LIBRARIES := \
        google-ps \
        android-support-v4 \

LOCAL_SRC_FILES := \
        $(call all-java-files-under, src) \
LOCAL_MODULE := AndroidLib
LOCAL_PACKAGE_NAME := AndroidLib

LOCAL_MODULE_TAGS := tests

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := google-ps:libs/google-play-services.jar

include $(BUILD_PACKAGE)

# additionally, build tests in sub-folders in a separate .apk
include $(call all-makefiles-under,$(LOCAL_PATH))

浏览器应用

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_JAVA_LIBRARIES := \
        android-common \
        guava \
        android-support-v13 \
        android-support-v4 \

LOCAL_SRC_FILES := \
        $(call all-java-files-under, src) \
        src/com/android/browser/EventLogTags.logtags

LOCAL_PACKAGE_NAME := Browser

LOCAL_PROGUARD_FLAG_FILES := proguard.flags

LOCAL_EMMA_COVERAGE_FILTER := *,-com.android.common.*


# We need the sound recorder for the Media Capture API.
LOCAL_REQUIRED_MODULES := SoundRecorder, AndroidLib

include $(BUILD_PACKAGE)
# additionally, build tests in sub-folders in a separate .apk
include $(call all-makefiles-under,$(LOCAL_PATH))

然后我做:

make -j Browser

它给了我:

packages/apps/Browser/src/com/android/browser/BrowserActivity.java:36: package com.om.AndroidLib does not exist
import com.om.AndroidLib.MainActivity;

【问题讨论】:

  • 您是否已将库项目的所有活动声明到主项目的清单中并带有包名。并检查库项目清单中标明的包名。
  • @MeenalSharma:我认为它应该与您使用 Eclipse 并将 A 定义为库然后将库添加到主项目中时相同。是否需要将 A Lib 的声明复制到 Main Project 中?
  • 是的,您必须复制,因为您运行的是主项目而不是库,并且当库项目的活动被调用时,它会从主项目中访问。
  • LOCAL_REQUIRED_MODULES 必须用空格分隔,而不是逗号(见android.mk

标签: android android-ndk android-source android-build android-framework


【解决方案1】:

更新

基本上你的问题是:

LOCAL_REQUIRED_MODULES := SoundRecorder, AndroidLib

告诉 Android 构建您的浏览器依赖于首先构建的 AndroidLib,但它不会以任何方式链接到 AndroidLib。为此,您需要:

LOCAL_JAVA_LIBRARIES := AndroidLib

除了要求AndroidLib 是java 库项目,使用构建类型:

include $(BUILD_JAVA_LIBRARY)

不幸的是,Java 库不能包含资源。并且无法在 Android 构建系统中将一个应用链接到另一个应用。

我们经常解决这个问题,坦率地说,这样做有点混乱。但我们发现的唯一解决方法是将所有资源直接包含在使用这些资源的应用程序中。对不起。


如何使您的 AndroidLib 成为 java 库并链接到它

您的 android 库可能应该构建为 java 库,而不是应用程序包。 所以而不是:

include $(BUILD_PACKAGE)

你应该这样做:

include $(BUILD_JAVA_LIBRARY)

然后你的库将与其他系统库一起被放置在out/target/product/generic/system/framework/AndroidLib.jar

此外,您不需要为 lib 提供 LOCAL_MODULE_NAME,它仅适用于应用程序。所以剥掉它。

您可能应该考虑将您的LOCAL_MODULE_TAGS 更改为:

LOCAL_MODULE_TAGS := user

tests 表示您的 lib 只应为测试而构建,user 表示为所有用户构建构建您的 lib(也隐含地用于工程构建)


在您的应用程序Android.mk 中,您应该添加一行:

LOCAL_JAVA_LIBRARIES := AndroidLib

这样您的应用将在类路径中使用AndroidLib 构建。


在您的应用程序AndroidManifest.xml 中,您还需要在application 标签中放置一个使用库:

<uses-library android:name="AndroidLib" />

最后你需要创建一个权限xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <library name="AndroidLib"
            file="/system/framework/AndroidLib.jar"/>
</permissions>

并更新您的产品配置文件,以便将 xml 文件部署到目标:

PRODUCT_COPY_FILES += device/XXX/libs/AndroidLib.xml:system/etc/permissions/AndroidLib.xml

device/XXX/libs/替换为权限xml文件的路径。


这就是我们在 Android 构建中添加和使用 Android 库的方式。我希望它有所帮助。 :)

【讨论】:

  • 我想我没有对你说得很清楚。 android 库实际上是一个拥有自己资源的 Android 项目。我按照你的指示做了很多 R 资源没有找到。我查看了 external/[libraries] ,我发现它们的作用与您所说的非常相似,但它们都是纯 Java Lib,但这里并非如此。
  • 有两种相关的Android库。当您制作 3rd 方应用程序时,您可以创建库项目类型(例如在 Eclipse 中)。这些将被编译到所有使用它们的应用程序中。但是当您从源代码构建 Android 操作系统时,没有 android 库项目的这种概念。然而,有一些 java 库将作为 jar 文件安装在目标上。但不幸的是,它们不能包含资源。您必须将所需的资源直接包含在应用程序中而不是库中,这是目前唯一可行的方式。对不起。
  • 我没有尝试过你的新方法,但你给出了很好的解释。我们可以从库的 res 到应用程序的符号链接而不是复制它们吗?或者我们可以在应用程序中定义 LOCAL_RESOURCE_DIRS 吗?我会回到这个。反正。谢谢你的解释。
  • @CuongThai:当然,您可以创建符号链接,但我不确定 LOCAL_RESOURCE_DIRS,您确实想同时使用 Browser 应用程序和 AndroidLib 资源中的资源。
  • 感谢@BjarkeFreund-Hansen 提供如此详细的解释。我正在寻找有关如何将 jar 文件添加到现有 android 本机项目的答案,并遇到了这个问题。你能建议我是否要添加一个jar文件,我应该如何添加它?
【解决方案2】:

我知道我正在将其从坟墓中挖掘出来,但是对于如何在AOSP 构建的应用程序。

这是我对两个项目所做的。 “main”是我为其构建 apk 的主要应用程序。 “util”是一个实用程序库,其中包含我要链接的资源。这两个项目都位于 external/seabold/{package} 中:

Android.mk in seabold/

LOCAL_PATH := $(call my-dir)

UTIL_PATH := $(LOCAL_PATH)/util

UTIL_JAVA_SRC := $(call all-java-files-under, util/src)

#Filter out if the util library isn't present
UTIL_RES_DIR := $(wildcard $(UTIL_PATH)/res)

include $(call all-subdir-makefiles)



Android.mk in seabold/main/

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_PACKAGE_NAME := main

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

#Since the BUILD_PACKAGE makefile expects java files to be relative paths,
#we need to add the ../ in front of each file (which is stored as relative
#to seabold/
LOCAL_SRC_FILES += $(patsubst %.java,../%.java,$(UTIL_JAVA_SRC))

#Make sure both packages' resources are included
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res $(UTIL_RES_DIR)

#Since we are including resouces for two packages (This app and the util lib),
#we need to tell aapt to generate an R.java for the util package as well
LOCAL_AAPT_FLAGS := --generate-dependencies --extra-packages com.seabold.util --auto-add-overlay

include $(BUILD_PACKAGE)

请注意这里以确保您正确地使用文件名。对我来说,UTIL_JAVA_SRC 中定义的文件是util/src/com/seabold/util/*.java 的形式。由于主应用程序的构建脚本期望 java 文件是 Android.mk 位置的相对路径,因此我添加了一个 ../ 以正确访问 util 库的路径。

资源的关键是 LOCAL_AAPT_FLAGS。这告诉资源打包器确保它为实用程序库中的包生成 R.java。没有这个,实用程序的所有资源都将被放入主应用程序 R.java,并且实用程序类将无法编译,因为它的 R.java 将丢失。

【讨论】:

    【解决方案3】:

    为了向框架添加预构建 jar 文件,我这样做了:

    1. 下找到包含 jar 和 Android.mk 文件的文件夹

      prebuilds/misc/common/

    Android.mk:

    LOCAL_PATH := $(call my-dir) 
    include $(CLEAR_VARS) 
    
    LOCAL_MODULE := <jar name> 
    LOCAL_MODULE_TAGS := optional 
    LOCAL_SRC_FILES := <jar name>.jar 
    LOCAL_MODULE_CLASS := JAVA_LIBRARIES 
    LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX) 
    
    include $(BUILD_PREBUILT) 
    
    1. 在 Android.mk 文件上运行 make:make prebuilds/misc/common/Android.mk

    2. 将 jar 文件添加到 frameworks/base/services/Android.mk:

    LOCAL_STATIC_JAVA_LIBRARIES := $(addprefix services.,$(services)) jar-name

    【讨论】:

      【解决方案4】:

      我偶然发现了一个关于 java 库如何访问资源的解决方案。资源作为单独的 apk 构建。 jar-lib 可以在其 Manifest 中如此说明的任何应用程序中使用。 java-library-code 具有资源apk 的R.java 并使用createPackageContext() 来访问实际资源。 createPackageContext() 获取 app-context 作为每个应用程序在使用需要访问资源的 java-lib-function 时必须提供的参数。

      我还没有深入了解 AOSP 构建系统,所以我希望我在这里记录的内容是有意义的。这也不是我的解决方案,我只是改进了一些其他开发人员在我的工作中创建的东西,所以我不知道他从哪里得到的方法。

      对于 resource-only-apk 我们有:

      Android.mk

      include $(CLEAR_VARS)
      
      LOCAL_PATH := $(call my-dir)
      LOCAL_PACKAGE_NAME := shared-resources
      LOCAL_MODULE_TAGS :=  optional
      LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_APPS)
      LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res 
      
      include $(BUILD_PACKAGE)
      

      AndroidManifest.xml

      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                      package="my.company.common.resources">
      <application android:hasCode="false"/>
      </manifest>
      

      对于 jar-lib,我们有:

      Android.mk

      LOCAL_PATH:= $(call my-dir)
      
      ####################
      # compile the jar  #
      include $(CLEAR_VARS)
      LOCAL_MODULE := helper-lib
      LOCAL_SRC_FILES := $(call all-java-files-under, src)
      
      # add package-context-ressources
      resource-intermediates := $(call intermediates-dir-for,APPS,shared-resources,,common)
      shared_res := $(resource-intermediates)/src/my/company/common/resources/R.java
      $(shared_res): $(resource-intermediates)/src/R.stamp
      LOCAL_GENERATED_SOURCES := $(shared_res)
      
      LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_JAVA_LIBRARIES)
      LOCAL_ADDITIONAL_DEPENDENCIES := helper-lib.xml
      include $(BUILD_JAVA_LIBRARY)
      
      ######################
      # deliver permisions #
      include $(CLEAR_VARS)
      LOCAL_MODULE := helper-lib.xml
      LOCAL_MODULE_CLASS := ETC
      LOCAL_MODULE_TAGS := optional
      LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/permissions
      LOCAL_SRC_FILES := helper-lib.xml
      include $(BUILD_PREBUILT)
      

      AndroidManifest.xml

      <?xml version="1.0" encoding="utf-8"?>
      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="my.company.helper">
          <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
          <uses-permission android:name="android.permission.MANAGE_USERS" />
          <application />
      </manifest>
      

      helper-lib.xml

      <?xml version="1.0" encoding="utf-8"?>
      <permissions>
          <library name="helper-lib" file="/vendor/framework/helper-lib.jar" />
      </permissions>
      

      最后但并非最不重要的一点是,我们如何在整个 makefile 中声明它们,该文件说明了要包含的所有内容 -> base_packages.mk

      PRODUCT_PACKAGES += \
          my.company.common \
          shared-resources \
          helper-lib
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-29
        • 1970-01-01
        相关资源
        最近更新 更多