Search code examples
androidandroid-studioandroid-annotations

How to use Android Annotations in a library (Android Studio)?


I have an android project in android studio. One of the modules is a library using android annotations. The other is an application which uses the library. Through much tweaking and googling I've managed to get the library project to generate the "" files. However, when I run the application it's not including the files, which I can see because it immdiately crashes when it can't find the Application "" class.

Library build.gradle

apply plugin: 'com.android.library'
apply plugin: 'android-apt'
def AAVersion = '3.0.1'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

configurations {
    apt
}

apt {
    arguments {
        androidManifestFile variant.outputs[0].processResources.manifestFile
        resourcePackageName 'com.hps.mobuyle.core'
        library "true"
    }
}


android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23

        // Enabling multidex support.
        multiDexEnabled true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    packagingOptions {
        exclude 'META-INF/license.txt'
        exclude 'META-INF/notice.txt'
    }

    sourceSets {
        main {
            jniLibs.srcDir 'libs'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:23.1.0'
    compile 'com.google.code.gson:gson:2.2.4'
    compile 'com.android.support:appcompat-v7:23.1.0'

    // android annotations
    apt "org.androidannotations:androidannotations:$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
}

Application build.gradle

apply plugin: 'com.android.application'

apply plugin: 'android-apt'
def AAVersion = '3.0.1'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

configurations {
    apt
}

apt {
    arguments {
        androidManifestFile variant.outputs[0].processResources.manifestFile
        resourcePackageName 'com.hps.mobuyle.core'
    }
}

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.hps.mobuyle.restaurant"
        minSdkVersion 16
        targetSdkVersion 23

        // Enabling multidex support.
        multiDexEnabled true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

}


dependencies {
    compile 'com.android.support:appcompat-v7:23.1.0'
    // android annotations
    apt "org.androidannotations:androidannotations" + ":$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
    compile project(':libraryProject')
}

Project settings.gradle

include ':libraryProject'
include ':applicationProject'

Full error output

10-24 13:54:41.890 17670-17670/? E/Zygote: v2
10-24 13:54:41.890 17670-17670/? E/Zygote: accessInfo : 0
10-24 13:54:41.980 17670-17670/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.hps.mobuyle.restaurant, PID: 17670
                                                   java.lang.RuntimeException: Unable to instantiate application com.android.tools.fd.runtime.BootstrapApplication: java.lang.IllegalStateException: java.lang.ClassNotFoundException: com.hps.mobuyle.core.MPApplication_
                                                       at android.app.LoadedApk.makeApplication(LoadedApk.java:676)
                                                       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6289)
                                                       at android.app.ActivityThread.access$1800(ActivityThread.java:221)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1860)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:158)
                                                       at android.app.ActivityThread.main(ActivityThread.java:7224)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
                                                    Caused by: java.lang.IllegalStateException: java.lang.ClassNotFoundException: com.hps.mobuyle.core.MPApplication_
                                                       at com.android.tools.fd.runtime.BootstrapApplication.createRealApplication(BootstrapApplication.java:220)
                                                       at com.android.tools.fd.runtime.BootstrapApplication.attachBaseContext(BootstrapApplication.java:239)
                                                       at android.app.Application.attach(Application.java:211)
                                                       at android.app.Instrumentation.newApplication(Instrumentation.java:1020)
                                                       at android.app.Instrumentation.newApplication(Instrumentation.java:1004)
                                                       at android.app.LoadedApk.makeApplication(LoadedApk.java:666)
                                                       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6289) 
                                                       at android.app.ActivityThread.access$1800(ActivityThread.java:221) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1860) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:158) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:7224) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
                                                    Caused by: java.lang.ClassNotFoundException: com.hps.mobuyle.core.MPApplication_
                                                       at java.lang.Class.classForName(Native Method)
                                                       at java.lang.Class.forName(Class.java:324)
                                                       at java.lang.Class.forName(Class.java:285)
                                                       at com.android.tools.fd.runtime.BootstrapApplication.createRealApplication(BootstrapApplication.java:209)
                                                       at com.android.tools.fd.runtime.BootstrapApplication.attachBaseContext(BootstrapApplication.java:239) 
                                                       at android.app.Application.attach(Application.java:211) 
                                                       at android.app.Instrumentation.newApplication(Instrumentation.java:1020) 
                                                       at android.app.Instrumentation.newApplication(Instrumentation.java:1004) 
                                                       at android.app.LoadedApk.makeApplication(LoadedApk.java:666) 
                                                       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6289) 
                                                       at android.app.ActivityThread.access$1800(ActivityThread.java:221) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1860) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:158) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:7224) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
                                                    Caused by: java.lang.ClassNotFoundException: Didn't find class "com.hps.mobuyle.core.MPApplication_" on path: DexPathList[[zip file "/data/app/com.hps.mobuyle.restaurant-2/base.apk"],nativeLibraryDirectories=[/data/app/com.hps.mobuyle.restaurant-2/lib/arm64, /vendor/lib64, /system/lib64]]
                                                       at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                       at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                                       at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                                       at java.lang.Class.classForName(Native Method) 
                                                       at java.lang.Class.forName(Class.java:324) 
                                                       at java.lang.Class.forName(Class.java:285) 
                                                       at com.android.tools.fd.runtime.BootstrapApplication.createRealApplication(BootstrapApplication.java:209) 
                                                       at com.android.tools.fd.runtime.BootstrapApplication.attachBaseContext(BootstrapApplication.java:239) 
                                                       at android.app.Application.attach(Application.java:211) 
                                                       at android.app.Instrumentation.newApplication(Instrumentation.java:1020) 
                                                       at android.app.Instrumentation.newApplication(Instrumentation.java:1004) 
                                                       at android.app.LoadedApk.makeApplication(LoadedApk.java:666) 
                                                       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6289) 
                                                       at android.app.ActivityThread.access$1800(ActivityThread.java:221) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1860) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:158) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:7224) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
                                                    Suppressed: java.lang.ClassNotFoundException: Didn't find class "com.hps.mobuyle.core.MPApplication_" on path: DexPathList[[dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-support-annotations-23.1.0_510f17cdc40968bee04a55acc3a74b072e08e08e-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_9-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_8-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_7-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_6-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_5-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_4-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_3-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_2-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_1-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slice_0-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-slf4j-api-1.7.10_57fc178fc2dace08d430739b21b0d50456c561f2-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-logback-android-core-1.1.1-3_79a748caea787f82e8fa3c69f01e9a3885b7ec32-classes.dex", dex file "/data/data/com.hps.mobuyle.restaurant/files/instant-run/dex/slice-logback-android-classic-1.1.1-3_c1b46ea01a968
10-24 13:54:42.010 3432-17684/? E/android.os.Debug: ro.product_ship = true
10-24 13:54:42.010 3432-17684/? E/android.os.Debug: ro.debug_level = 0x4f4c
10-24 13:54:42.010 3432-17684/? E/android.os.Debug: sys.mobilecare.preload = false

Build warnings

Warning:The following options were not recognized by any processor: '[androidManifestFile, resourcePackageName]'

Solution

  • After looking at your library build.gradle, i found one possible problem. You should always pass strings to the annotation processing options, true may not work here, "true" should work.

    apt {
        arguments {
            androidManifestFile variant.outputs[0].processResources.manifestFile
            resourcePackageName 'com.hps.mobuyle.core'
            library "true"
        }
    }
    

    I checked out the stripped down project on GitHub.

    The main problem is that the project has an unconventional layout, however the different project locations are not configured properly. This is why Gradle does not know about the sources at all, and does not include the compiled classes in the APK.

    This is what is needed to configure this project layout:

    Set the manifest file location: manifest.srcFile 'app/src/main/AndroidManifest.xml'

    Add Java source folders: java.srcDirs += 'app/src/main/java'

    Configure the JNI folders: jniLibs.srcDirs += 'app/libs'

    Add local dependency jars: compile fileTree(dir: 'app/libs', include: ['*.jar']) (note these are under the app folder

    I also updated the version of the android-apt plugin and i also removed the not needed android.applicationVariants.each block, which was the way the configure annotation processing before the plugin. Now it is done by the plugin itself.

    I also fixed the AA annotation processing parameters in the app project, because it wrongly pointed to the lib project package name: resourcePackageName 'com.hps.mobuyle.restaurant'

    The fill set of changes can be found in this commit.