Search code examples
androidmakefileandroid-manifestaarleakcanary

How do I include an AAR in an app using Android Make?


I'm trying to include a library (LeakCanary) when building an app with Make, but I'm running into a couple of different issues depending on how I build and include it.

Here's the make file that I use to build LeakCanary:

# Build LeakCanary aar
#=========================

include $(CLEAR_VARS)
LOCAL_MODULE := LeakCanary
LOCAL_MODULE_TAGS := optional
LOCAL_MANIFEST_FILE := ./leakcanary/leakcanary-android/src/main/AndroidManifest.xml
LOCAL_SRC_FILES := $(call all-java-files-under, leakcanary/leakcanary-android/src/main/java)
LOCAL_SRC_FILES += $(call all-java-files-under, leakcanary/leakcanary-analyzer/src/main/java)
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/leakcanary/leakcanary-android/src/main/res
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
LOCAL_JAVACFLAGS := -encoding UTF-8
LOCAL_USE_AAPT2 := true
LOCAL_SDK_VERSION := current
LOCAL_JAR_EXCLUDE_FILES := none
LOCAL_STATIC_JAVA_LIBRARIES += \
    haha \
    leakcanary_watcher \
    trove4j

include $(BUILD_STATIC_JAVA_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE := haha
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := leakcanary/libs/haha-2.0.4.jar
LOCAL_UNINSTALLABLE_MODULE := true
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)

LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE := leakcanary_watcher
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := leakcanary/libs/leakcanary-watcher-1.6.1.jar
LOCAL_UNINSTALLABLE_MODULE := true
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)

LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE := trove4j
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := leakcanary/libs/trove4j-20160824.jar
LOCAL_UNINSTALLABLE_MODULE := true
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)

I then add the library to the app:

LOCAL_STATIC_ANDROID_LIBRARIES += \
    LeakCanary

If I build it this way, the app APK includes all the resources from LeakCanary, but the manifests are not merged. LeakCanary's manifest file declares an activity that then can't be found a runtime.

If I instead do:

make LeakCanary /usr/build/out/p/target/common/obj/JAVA_LIBRARIES/LeakCanary_intermediates/javalib.aar

And then copy it to the app and include it like:

LOCAL_STATIC_JAVA_AAR_LIBRARIES += \
    leakcanary

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += \
    leakcanary:libs/leakcanary.aar

The manifests seem to be merged, but the library resources are not (yet?) included:

FAILED: /usr/build/out/p/target/product/platform/obj/APPS/app_intermediates/package-res.apk /usr/build/out/p/target/common/obj/APPS/app_intermediates/aapt2.srcjar /usr/build/out/p/target/common/obj/APPS/app_intermediates/extra_packages /usr/build/out/p/target/common/obj/APPS/app_intermediates/src/R.stamp /usr/build/out/p/target/common/obj/APPS/app_intermediates/proguard_options 
/bin/bash /usr/build/out/p/target/product/platform/obj/APPS/app_intermediates/package-res.apk.rsp
warn: ignoring density 'mdpi-v4' for -c option.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:139: error: resource xml/leak_canary_file_paths (aka com.company.app:xml/leak_canary_file_paths) not found.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:144: error: resource mipmap/leak_canary_icon (aka com.company.app:mipmap/leak_canary_icon) not found.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:144: error: resource string/leak_canary_display_activity_label (aka com.company.app:string/leak_canary_display_activity_label) not found.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:144: error: resource style/leak_canary_LeakCanary.Base (aka com.company.app:style/leak_canary_LeakCanary.Base) not found.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:158: error: resource mipmap/leak_canary_icon (aka com.company.app:mipmap/leak_canary_icon) not found.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:158: error: resource string/leak_canary_storage_permission_activity_label (aka com.company.app:string/leak_canary_storage_permission_activity_label) not found.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:158: error: resource mipmap/leak_canary_icon (aka com.company.app:mipmap/leak_canary_icon) not found.
/usr/build/out/p/target/common/obj/APPS/app_intermediates/AndroidManifest.xml:158: error: resource style/leak_canary_Theme.Transparent (aka com.company.app:style/leak_canary_Theme.Transparent) not found.
error: failed processing manifest.

However, if I then include the LeakCanary resources like this, the build works:

LOCAL_RESOURCE_DIR += \
  $(LOCAL_PATH)/leakcanary/leakcanary-android/src/main/res

I'm a bit lost on the difference between LOCAL_STATIC_ANDROID_LIBRARIES and LOCAL_STATIC_JAVA_AAR_LIBRARIES and which I should be using here.

Based on what I've seen it seems like LOCAL_STATIC_JAVA_AAR_LIBRARIES includes and merges the manifests, but does not include resources unless they're specified with LOCAL_RESOURCE_DIR. On the other side, LOCAL_STATIC_ANDROID_LIBRARIES includes the resources without having to specify LOCAL_RESOURCE_DIR, but it doesn't merge the manifests.

I'm looking for some way of getting both the manifest merge and the resource include to work, without having to explicitly add the resources to LOCAL_RESOURCE_DIR.

Any ideas on what I can do to make this work? I would like to make LeakCanary available to other apps as well, which is why I'm trying to build it as a module. My last option (as I see it), that I'm trying to avoid, is to let all apps build and include the LeakCanary dependencies in their make files.


Solution

  • I was able to get around this by building two modules, LeakCanary and LeakCanary-res.

    LOCAL_MODULE := LeakCanary-res
    LOCAL_MODULE_TAGS := optional
    LOCAL_MANIFEST_FILE := leakcanary-android/src/main/AndroidManifest.xml
    LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/leakcanary-android/src/main/res
    LOCAL_USE_AAPT2 := true
    LOCAL_SDK_VERSION := current
    
    include $(BUILD_STATIC_JAVA_LIBRARY)
    

    And then include them like:

    LOCAL_STATIC_ANDROID_LIBRARIES += \
        LeakCanary-res
    
    LOCAL_STATIC_JAVA_AAR_LIBRARIES += \
        LeakCanary-prebuilt