Clojure on Android - Workflow Setup I

Last time we did a brief overview of what you should know about Clojure Android before getting started with it.

So now it's time to start the long procedure of getting all the stuff you need to run on your machine. I assume you have a Mac, but these instructions will likely run on a Linux and possibly on Windows as well.

What you will get:
  • you'll be able to compile and run on device Clojure Android projects (this post)
  • you'll be able to interact with the app running on device through a REPL and modify it while it's running (next post)
What you need:
  • a pc, preferably Linux/Mac, Windows will do but you might have to adapt these instructions
  • must have at least JDK 1.7
  • an Android device with at least Android SDK version >=15 (Android 4.0.3 or higher)
  • alternatively a lot of patience because you'll have to deal with the Android Emulator
  • lein already installed

Install Android

Downloading the entire internet is a classic side-effect of installing the Android SDK on your machine.
Watch out for the standard installer trying to get you to download all the versions of all the Androids.
I list below the only things you need to download through the android tool.

  • Option 1: download installer.
    You can get the Android Studio IDE as well, or just the SDK. We won't use Android Studio with Clojure so that's up to you.
  • Option 2: you can install the Android SDK through brew with brew install android-sdk and then add export ANDROID_HOME=/usr/local/opt/android-sdk to your .bash_profile.

After getting the SDK you can use

$ android

to download the rest of the SDK.
I suggest you stick to one API version, as downloading more than one will use quite a bit of space.

At the time of writing the latest SDK version is 23, you also have to check what versions your device supports.

You'll need to install through android:

  • Android SDK tools
  • Android SDK Platform-tools
  • Android SDK Build-tools (>=20)
  • SDK platform (>=15)
  • Google APIs (>=15)
  • Android Support Repository

that should do it.

On Windows you might have to set up USB drivers for your specific device as well.

Clojure Setup

I assume you already have installed lein as I listed in the pre-requisites.

Using lein new droid <nameproject> <packagename> <opts>
will automatically get you the lein droid template.

Example (we'll make this app in the next posts):

$ lein new droid anfocal com.lambdacat.anfocal :activity AnFocalActivity :target-sdk 23 :app-name AnFocal

There are some things you should know before choosing a project name and a package name:

  • in the project name you can't use hyphens or capital letters. Yes I know, it's annoying.
  • the package name must be a reversed internet domain name. The point is to use a domain you own. Use com.example.* at your own risk.
  • the target-sdk must be one your target device supports and you have installed from the android command. Also it must be >= 15
Make a project

So I'll assume you ran the previous command and you have the anfocal app folder on your machine.

An Focal means The Word in Irish Gaelic.
That might merit some explanation as of why:

  1. I'm learning Irish as a hobby
  2. I'm going to speak about Clojure on Android at the fantastic FunctionalKats conference in Dublin in September.

using as an example an app about Irish Gaelic souns quite appropriate to me. So, confusing app titles explained away, we can resume our setup.

You'll have a folder tree that looks like this:

.
├── AndroidManifest.template.xml
├── LICENSE
├── README.md
├── assets
├── build
│   ├── proguard-minify.cfg
│   └── proguard-multi-dex.cfg
├── project.clj
├── res
│   ├── anim
│   │   └── splash_rotation.xml
│   ├── drawable
│   │   └── splash_background.xml
│   ├── drawable-hdpi
│   │   ├── ic_launcher.png
│   │   ├── splash_circle.png
│   │   ├── splash_droid.png
│   │   └── splash_hands.png
│   ├── drawable-mdpi
│   │   └── ic_launcher.png
│   ├── layout
│   │   └── splashscreen.xml
│   └── values
│       └── strings.xml
└── src
    ├── clojure
    │   └── com
    │       └── lambdacat
    │           └── anfocal
    │               └── main.clj
    └── java
        └── com
            └── lambdacat
                └── anfocal
                    └── SplashActivity.java

You can't compile this project yet.
First you have to add the android sdk path to the project.clj file.

You'll have to add it inside the :android map, under :sdk-path:

:android {;; Specify the path to the Android SDK directory.
          :sdk-path "/usr/local/opt/android-sdk"

If you installed with brew it will be /usr/local/opt/android-sdk.

There are many interesting options in the project.clj file that I won't go through at this point, but it's worth a careful look.

Compile and run

Running on device requires that its setting allow USB debugging and Unknown Sources. You have to activate Android Developer mode on your device to access those Settings. Usually you do that by tapping 7 times on the device about information. (Odd, uh?)
I have seem many people flounder and curse before asking or doing a Google search to find that out...

Once you've done that, attach with an USB cable and check with adb devices that your device is available to adb.

If you have trouble with adb devices take a look at the troubleshooting section at the end of the article.

Once that is taken care of, you can run
lein droid doall and lein droid will start compiling the app.

That includes these steps:

  • downloading the dependencies
  • generating the manifest
  • generating the R.java files
  • building the app and libraries files
  • creating the DEX
  • crunching the resources
  • packaging them
  • creating the APK
  • signing the APK with ~/.android/debug.keystore
  • aligning the APK
  • and attempting to run it on a device connected with a USB cable to your machine

Eventually the app will run on your device.

If you want to take advantage of Skummet (see past post) to have a faster app, we'll setup it in a following post.

Next Steps

Now you have an app you can run either on emulator or by attaching a device. Attaching a device is faster, strangely enough.

What we want to do next is:

  • get to know better lein droid
  • setup Emacs for interactive development
  • setup using Skummet to compile our app

Next post: Workflow Setup II, Live Coding

Troubleshooting: Getting your device to show up on adb

Sometimes devices connected via USB can be quite stubborn and refuse to show up.

The successful output is:

$ adb devices
List of devices attached
62cec424     device

If you've followed the above instructions:

  • install your device's USB driver if you are on Windows
  • activate Developer Mode on device
  • allow Unknown Sources
  • allow USB debugging
  • make sure to accept the Give Permission modal popup that will appear on your device when you connect it.

your device should show up. But if it doesn't try the usual 'turn it on and off again' approach.
Take also into account that sometimes the drivers on Windows are tricky to find, or work only spoadically.