Nick Nick - 23 days ago 9
Android Question

How to develop a library and an application side-by-side in Android Studio?

I'm currently developing both a library (with no activities) and an application that depends on the library. Currently, I have these as separate projects, and I can copy the generated .aar file from the library project into the application project's libs folder, and re-sync gradle. However, this is an inefficient process because I have to rebuild and manually re-copy the .aar file every time I make a change to the library project. My question is, how can I streamline this process so that my application automatically uses the library's most recently generated .aar file?

Answer

how can I streamline this process so that my application automatically uses the library's most recently generated .aar file?

Option #1: Dedicated Library

Step #1: Put your app project and the library project as children of a common root directory for the overall project. For the purposes of this answer, I'll call these app/ and library/, respectively.

Step #2: In the top level (i.e., the common root directory), have a settings.gradle file that lists these modules:

include ':app', ':library'

Step #3: In the top level, have a build.gradle file that sets up the Gradle for Android plugin and any other common stuff of interest, such as:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

(note that the above file is what you get from a native Android Studio project, created by the IDE)

Step #3: In the library/ directory, have a build.gradle file that uses the com.android.library plugin

Step #4: In the app/ directory, have a build.gradle file that has compile project(':library') in its dependencies to pull in the library

It may be that your AAR is the deliverable, not the app (e.g., the library is an open source one for community use, and the app is a demo app). In that case, you might use debugCompile in app/ to pull in the local library project for debug builds, but have releaseCompile to pull in the AAR from a published source, to confirm that you can build from the same thing that users of the AAR use.

Most of my CWAC libraries are set up this way (e.g., cwac-richedit).

Option #2: Publish the AAR Locally

You can use the maven plugin and the uploadArchives task to upload to a local Maven-style repo:

apply plugin: 'maven'

uploadArchives {
    repositories.mavenDeployer {
        pom.groupId = PUBLISH_GROUP_ID
        pom.artifactId = PUBLISH_ARTIFACT_ID
        pom.version = PUBLISH_VERSION

        repository(url: LOCAL_REPO)
    }
}

Here, my constants are pulled in from a gradle.properties file, and LOCAL_REPO is a file:/// URL pointing to a local repo. You can then run gradle uploadArchives to generate the AAR and push it to the local repo.

Then, your app can have a maven { url LOCAL_REPO } closure in the repositories closure, and can pull in the AAR artifact from there as if it was coming from a public repo (e.g., Maven Central).

My CWAC libraries use the uploadArchives task, but only for publishing to my local mirror of my Amazon S3-hosted Maven repo.

This approach would be if you really wanted to work off of the AAR, but wanted to do so from multiple projects. Note that you can certainly publish this to some other sort of Maven repo (e.g., a Sonatype server) for enterprise use.

Option #3: Mod a Module to Point to the Library Elsewhere

This is Pavel Dudka's approach in his answer. I haven't tried this. Off the cuff, this would be a good approach if you want to depend upon the library from multiple apps, but you're not really concerned about having an actual AAR as a thing to distribute around.

And I'm sure there are other options than these three.