Wednesday, October 16, 2013

Android Studio + Gradle + Android Annotations

I've been trying to migrate to Android Studio and Gradle for a little while now and I think I finally figured it out.

So far these are the key points you need to know.

  • You don't need to really configure Android Studio to do packaging or code generation 
    • this is a small but significant difference when moving from Eclipse.  Android Studio fully uses the Gradle build system so tweaking options in it will either have no effect or screw things up.  
  • Android Studio is really focused on editing code not building applications (that's where Gradle comes in).  
    • I haven't deviated a whole lot from their default structure - I'm pretty certain you can anticipate "issues" if you convert a project or try to deviate from the convention.
    • The project structure in Android Studio is similar to Maven, although it can be overridden in your gradle file.


I was pretty new coming into Gradle and watching this video helped quite a bit: http://youtu.be/LCJAgPkpmR0 - it's the Goolge I/O 2013 New Android Build System talk.

To get up and running very quickly all you have to do is create a new project. In the same directory as your source directory create two directories :compileLibs and libs.  AndroidAnnotations has a code generation library called androidannotations-2.7.1.jar and their api (similarly) named androidannotations-api-2.7.1.jar.  The api library goes into the libs directory and the non-api lib goes into compile libs.

Once you have that setup all you have to do is drop this Gradle file in and you're off and running:
buildscript {
    repositories {
        mavenLocal()
        maven { url 'http://repo1.maven.org/maven2'}
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}

apply plugin: 'android'

repositories {
    mavenCentral()
    maven {
        url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
}

configurations {
    compile
    androidannotations.extendsFrom(compile)
}

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    androidannotations fileTree(dir: 'compileLibs', include: '*.jar')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"
}

/*
over riding the android annotations output directory:
https://www.flexlabs.org/2013/05/support-android-annotations-in-gradle-projects
 */
def annotationDirs = file('src/main/aa_gen')

task annotationsDir {
    outputs.dir annotationDirs

    doFirst {
        if (!annotationDirs.isDirectory()) {
            println 'Creating: ' + annotationDirs
            annotationDirs.mkdirs()
        }
    }
}

tasks.clean.dependsOn tasks.cleanAnnotationsDir

afterEvaluate { project ->
    android.applicationVariants.each { variant ->
        variant.javaCompile.dependsOn annotationsDir
        variant.javaCompile.options.compilerArgs += [
                '-classpath', configurations.compile.asPath,
                '-processorpath', configurations.androidannotations.asPath,
                '-processor', 'com.googlecode.androidannotations.AndroidAnnotationProcessor',
                '-AandroidManifestFile=' + variant.processResources.manifestFile,
                '-s', annotationDirs
        ]
    }
}

Once I executed a gradle assemble command I did have to right click on the aa_gen folder and say "Mark Directory as Sources Root"

I think that's all I had to do in the end.  You should be able to be up and running in minutes (instead of weeks like me).

Happy Coding!

-Aaron


No comments: