Monday, May 27, 2013

ActionBarSherlock in Android Studio 0.1

[1st UPDATE: In Android Studio 0.1.1 the project structure of a new project has changed slightly: The name of top level directory is now postfixed with 'Project'. Everything else works as described.
2nd UPDATE, 23 June 2013: Fixed the build.gradle file for Android Studio 0.1.6
3rd UPDATE, 25 June 2013: Added a section to reflect latest changes in the Gradle Plugin and handling of the support library]

Note: While this guide uses ActionBarSherlock as an example the very same procedure will work for many library projects.

Since Android Studio was released as "Early Access Preview" there has been a lot of confusion how to use ActionBarSherlock and other library projects in it. Many people were successful when they imported projects from Eclipse after using ADT's export functionality but there was no how-to for projects created in Studio. I've been struggling with it myself for many hours.
After Xavier Ducrohet posted a little comment on Goolge+ it finally turned out that the problem essentially was caused by a misconception and lack of documentation: Android Studio's UI for managing dependencies is useless for the gradle based build system. And so are all the guides proposing a IntelliJ kind of dependency management.You have to manually edit your dependencies!

So here's a step-by-step guide how to integrate ActionBarSherlock into your Android Studio project:


Create a new project "SherlockTest":


Click "Next" until you're done:




After the wizard has finished you will find a new project with the following structure:


Now you need to put a copy of ActionBarSherlock into your project: Open a terminal, 'cd' into your project, create a 'libraries' directory and clone ActionBarSherlock from github:

[fex@yerbouti ~]$cd ~/AndroidStudioProjects/SherlockTest/
[fex@yerbouti SherlockTest]$mkdir libraries
[fex@yerbouti SherlockTest]$cd libraries
[fex@yerbouti libraries]git clone git://github.com/JakeWharton/ActionBarSherlock.git

After cloning ABS the project structure in Android Studio will show the newly added directories:


Now, you need to tell your build system that those directories exist by editing ~/AndroidStudioProjects/SherlockTest/settings.gradle. Just add the path to your library so that settings.gradle looks like this:

include ':SherlockTest', ':libraries:ActionBarSherlock:actionbarsherlock'

Next, create a build.gradle file in libraries/ActionBarSherlock/actionbarsherlock. Just copy the one from SherlockTest-SherlockTest (you can do this using Ctrl-C and Ctrl-V in Android Studio). You need to edit it a bit. So open the build.gradle file in libraries/ActionBarSherlock/actionbarsherlock change the 'apply-plugin' line to mark this as a library and add a sourceSet section to the android section. The whole build.gradle file should look like this now:

buildscript {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4'
    }
}
apply plugin: 'android-library'

dependencies {
    compile files('libs/android-support-v4.jar')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 16
    }
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        instrumentTest.setRoot('tests')
    }
}

Now you can add the dependency to your main project by editing the build.gradle file located in the SherlockTest-SherlockTest subtree in the project structure. Just add

compile project(':libraries:ActionBarSherlock:actionbarsherlock')

to the dependencies section.
[EDIT: As of Android Studio 0.1.6 you have to remove the dependency on support-v4.jar as well. It is already referenced by ABS.]
[EDIT 25 June 2013: See additional notes below for the right way to referencing the support library!]

So the whole build.gradle file looks like this:

buildscript {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4'
    }
}
apply plugin: 'android'

dependencies {
    compile project(':libraries:ActionBarSherlock:actionbarsherlock')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 16
    }
}

That's it! Now you can use Sherlock* classes in Android Studio and build your project from Studio as well. You might need to restart Android Studio or reload you project to get autocomplete of Sherlock* classes though.

Additional notes

While it all works as described you might want to tweak you build.gradle files a bit more.


Use latest Android Gradle Plugin

First, in order to always use the most recent version of the Android Gradle Plugin you should change all occurences of

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

to

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

Referencing the support library the right way

Second, you should not reference the support library the way it's done above. This only works if there's exactly one library depending on it. The right way to do it is by using the Android Support Repository. If you haven't installed it already you should do so using the SDK Manager from Studio. It's located in the "Extras" section.
After you have it installed you can reference the support library by replacing

dependencies {
    compile files('libs/android-support-v4.jar')
}

with

dependencies {
    compile 'com.android.support:support-v4:13.0.0'
}

You should also add this to the main build.gradle file (not the one in the top level directory) so that it reads:

buildscript {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4.+'
    }
}
apply plugin: 'android'

dependencies {
    compile 'com.android.support:support-v4:13.0.0'
    compile project(':libraries:ActionBarSherlock:actionbarsherlock')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 16
    }
}