Wednesday, May 23, 2012

android development on Command Line without Eclipse

On Windows, all command-line, no Eclipse, no hard-coded PATH/CLASSPATH, generic/reusable batch files, using only ANT and any text editor.
(I put everything in c:\DATA so I can drag / drop my entire PC setup in one move).
  • download jdk 1.6 to c:\DATA\tools
  • download android sdk to c:\DATA\tools\Android
  • cd to C:\DATA\tools\Android\android-sdk\tools and execute android list targets
  • execute android create project -t <highest target-id from above> -n AppName -p <path-to-workspace>/AppName -a SomeActivity -p com.yourdomain.AppName
e.g.
C:\DATA\tools\Android\android-sdk\tools\android create project -t 3 -n SomeApp -p c:\DATA\jbones\SomeApp -a SomeActivity -k com.jbones.android.SomeApp


Successful output should look like below
Created project directory: c:\DATA\jbones\SomeApp
Created directory C:\DATA\jbones\SomeApp\src\com\jbones\android\SomeApp
Added file c:\DATA\jbones\SomeApp\src\com\jbones\android\SomeApp\SomeActivity.ja
va
Created directory C:\DATA\jbones\SomeApp\res
Created directory C:\DATA\jbones\SomeApp\bin
Created directory C:\DATA\jbones\SomeApp\libs
Created directory C:\DATA\jbones\SomeApp\res\values
Added file c:\DATA\jbones\SomeApp\res\values\strings.xml
Created directory C:\DATA\jbones\SomeApp\res\layout
Added file c:\DATA\jbones\SomeApp\res\layout\main.xml
Created directory C:\DATA\jbones\SomeApp\res\drawable-hdpi
Created directory C:\DATA\jbones\SomeApp\res\drawable-mdpi
Created directory C:\DATA\jbones\SomeApp\res\drawable-ldpi
Added file c:\DATA\jbones\SomeApp\AndroidManifest.xml
Added file c:\DATA\jbones\SomeApp\build.xml
Added file c:\DATA\jbones\SomeApp\proguard-project.txt

  • download ant 1.7 (jars version...22 jars as of this writing) to c:\DATA\jbones\SomeApp\libs
ant-antlr.jar
ant-apache-bcel.jar
ant-apache-bsf.jar
ant-apache-log4j.jar
ant-apache-oro.jar
ant-apache-regexp.jar
ant-apache-resolver.jar
ant-apache-xalan2.jar
ant-commons-logging.jar
ant-commons-net.jar
ant-jai.jar
ant-javamail.jar
ant-jdepend.jar
ant-jmf.jar
ant-jsch.jar
ant-junit.jar
ant-junit4.jar
ant-launcher.jar
ant-netrexx.jar
ant-swing.jar
ant-testutil.jar
ant.jar
  • create file named  C:\DATA\jbones\SomeApp\cpappend.bat (to dynamically append CLASSPATH entries) with contents ....

set _LIBJARS=%_LIBJARS%;%1
  • create file named c:\DATA\jbones\SomeApp\setenv_1.6.0_12.bat (to dynamically set environment variables) with contents ....
echo off
set CLASSPATH=
set TOOLS=C:\DATA\tools
set JAVA_HOME=%TOOLS%\jdk1.6.0_12
set PROJECT_ROOT=c:\DATA\jbones\SomeApp
set _LIBJARS=
for %%i in (%PROJECT_ROOT%\libs\*.*) do call cpappend.bat %%i
for %%i in (%PROJECT_ROOT%\libs\ext\*.*) do call cpappend.bat %%i
for %%i in (%TOOLS%\*.*) do call cpappend.bat %%i
for %%i in (%JAVA_HOME%\lib\*.*) do call cpappend.bat %%i
set CLASSPATH=%CLASSPATH%;%_LIBJARS%
  • create file named C:\DATA\jbones\SomeApp\build_debug.bat with contents ....
echo off
set JAVA_HOME=
set PATH=
set CLASSPATH=
call setenv_1.6.0_12
echo using CLASSPATH %_LIBJARS%
echo using JAVA_HOME %JAVA_HOME%
"%JAVA_HOME%\bin\java" -classpath %_LIBJARS% org.apache.tools.ant.Main debug
echo [JBONES_PROJECT_BUILT]
pause
  • create file named c:\DATA\jbones\SomeApp\install_debug with contents ....
echo off
set JAVA_HOME=
set PATH=
set CLASSPATH=
call setenv_1.6.0_12
echo using CLASSPATH %_LIBJARS%
echo using JAVA_HOME %JAVA_HOME%
"%JAVA_HOME%\bin\java" -classpath %_LIBJARS% org.apache.tools.ant.Main installd
echo [JBONES_PROJECT_INSTALLED]
pause
  • execute c:\DATA\jbones\SomeApp\build_debug (builds project)
Successful output should look like below (if you get a bunch of [dx] warnings about inner classes Enclosing  Method attributes this merely means the jars - likely ANT jars - were compiled with a prior version than the JDK being used by the build - in this case 1.6 ... this can be ignored or you can rebuild ANT using 1.6)

C:\DATA\jbones\SomeApp>echo off
using CLASSPATH ;C:\DATA\jbones\SomeApp\libs\ant-antlr.jar;C:\DATA\jbones\SomeAp
p\libs\ant-apache-bcel.jar;C:\DATA\jbones\SomeApp\libs\ant-apache-bsf.jar;C:\DAT
A\jbones\SomeApp\libs\ant-apache-log4j.jar;C:\DATA\jbones\SomeApp\libs\ant-apach
e-oro.jar;C:\DATA\jbones\SomeApp\libs\ant-apache-regexp.jar;C:\DATA\jbones\SomeA
pp\libs\ant-apache-resolver.jar;C:\DATA\jbones\SomeApp\libs\ant-apache-xalan2.ja
r;C:\DATA\jbones\SomeApp\libs\ant-commons-logging.jar;C:\DATA\jbones\SomeApp\lib
s\ant-commons-net.jar;C:\DATA\jbones\SomeApp\libs\ant-jai.jar;C:\DATA\jbones\Som
eApp\libs\ant-javamail.jar;C:\DATA\jbones\SomeApp\libs\ant-jdepend.jar;C:\DATA\j
bones\SomeApp\libs\ant-jmf.jar;C:\DATA\jbones\SomeApp\libs\ant-jsch.jar;C:\DATA\
jbones\SomeApp\libs\ant-junit.jar;C:\DATA\jbones\SomeApp\libs\ant-junit4.jar;C:\
DATA\jbones\SomeApp\libs\ant-launcher.jar;C:\DATA\jbones\SomeApp\libs\ant-netrex
x.jar;C:\DATA\jbones\SomeApp\libs\ant-swing.jar;C:\DATA\jbones\SomeApp\libs\ant-
testutil.jar;C:\DATA\jbones\SomeApp\libs\ant.jar;C:\DATA\jbones\SomeApp\libs\out
.txt;C:\DATA\tools\jdk1.6.0_12\lib\ct.sym;C:\DATA\tools\jdk1.6.0_12\lib\dt.jar;C
:\DATA\tools\jdk1.6.0_12\lib\htmlconverter.jar;C:\DATA\tools\jdk1.6.0_12\lib\ir.
idl;C:\DATA\tools\jdk1.6.0_12\lib\jawt.lib;C:\DATA\tools\jdk1.6.0_12\lib\jconsol
e.jar;C:\DATA\tools\jdk1.6.0_12\lib\jvm.lib;C:\DATA\tools\jdk1.6.0_12\lib\orb.id
l;C:\DATA\tools\jdk1.6.0_12\lib\tools.jar
using JAVA_HOME C:\DATA\tools\jdk1.6.0_12
Buildfile: C:\DATA\jbones\SomeApp\build.xml

-set-mode-check:

-set-debug-files:

-set-debug-mode:

-debug-obfuscation-check:

-setup:
     [echo] Creating output directories if needed...
    [mkdir] Created dir: C:\DATA\jbones\SomeApp\bin\res
     [echo] Gathering info for SomeApp...
    [setup] Android SDK Tools Revision 19
    [setup] Project Target: Android 4.0.3
    [setup] API level: 15
    [setup]
    [setup] ------------------
    [setup] Resolving library dependencies:
    [setup] No library dependencies.
    [setup]
    [setup] ------------------
    [setup] API<=15: Adding annotations.jar to the classpath.
    [setup]
    [setup] ------------------
    [setup] WARNING: No minSdkVersion value set. Application will install on all
 Android versions.

-build-setup:
    [mkdir] Created dir: C:\DATA\jbones\SomeApp\gen
    [mkdir] Created dir: C:\DATA\jbones\SomeApp\bin\classes

-pre-build:

-code-gen:
     [echo] ----------
     [echo] Handling aidl files...
     [aidl] No AIDL files to compile.
     [echo] ----------
     [echo] Handling RenderScript files...
[renderscript] No RenderScript files to compile.
     [echo] ----------
     [echo] Handling Resources...
     [aapt] Generating resource IDs...
     [echo] ----------
     [echo] Handling BuildConfig class...
[buildconfig] Generating BuildConfig class.

-pre-compile:

-compile:
    [javac] Compiling 3 source files to C:\DATA\jbones\SomeApp\bin\classes

-post-compile:

-obfuscate:

-dex:
      [dex] Converting compiled files and external libraries into C:\DATA\jbones
\SomeApp\bin\classes.dex...
-crunch:
   [crunch] Crunching PNG Files in source dir: C:\DATA\jbones\SomeApp\res
   [crunch] To destination dir: C:\DATA\jbones\SomeApp\bin\res
   [crunch] Processing im
   [crunch] age to cache: C:\DATA\jbones\SomeApp\res\drawable-hdpi\ic_launcher.p
ng => C:\DATA\jbones\SomeApp\bin\res\drawable-hdpi\ic_launcher.png
   [crunch]   (processed image to cache entry C:\DATA\jbones\SomeApp\bin\res\dra
wable-hdpi\ic_launcher.png: 0% size of source)
   [crunch] Processing image to cache: C:\DATA\jbones\SomeApp\res\drawable-ldpi\
ic_launcher.png => C:\DATA\jbones\SomeApp\bin\res\drawable-ldpi\ic_launcher.png
   [crunch]   (processed image to cache entry C:\DATA\jbones\SomeApp\bin\res\dra
wable-ldpi\ic_launcher.png: 0% size of source)
   [crunch] Processing image to cache: C:\DATA\jbones\SomeApp\res\drawable-mdpi\
ic_launcher.png => C:\DATA\jbones\SomeApp\bin\res\drawable-mdpi\ic_launcher.png
   [crunch]   (processed image to cache entry C:\DATA\jbones\SomeApp\bin\res\dra
wable-mdpi\ic_launcher.png: 0% size of source)
   [crunch] Crunched 3 PNG files to update cache

-package-resources:
     [aapt] Creating full resource package...

-package:
[apkbuilder] Current build type is different than previous build: forced apkbuil
der run.
[apkbuilder] Creating SomeApp-debug-unaligned.apk and signing it with a debug ke
y...

-post-package:

-do-debug:
 [zipalign] Running zip align on final apk...
     [echo] Debug Package: C:\DATA\jbones\SomeApp\bin\SomeApp-debug.apk
[propertyfile] Creating new property file: C:\DATA\jbones\SomeApp\bin\build.prop

[propertyfile] Updating property file: C:\DATA\jbones\SomeApp\bin\build.prop
[propertyfile] Updating property file: C:\DATA\jbones\SomeApp\bin\build.prop
[propertyfile] Updating property file: C:\DATA\jbones\SomeApp\bin\build.prop

-post-build:

debug:

BUILD SUCCESSFUL
Total time: 20 seconds
[JBONES_PROJECT_BUILT]
Press any key to continue . . .
  • execute  c:\DATA\tools\Android\android-sdk\tools\android avd (an AVD is an emulator)
  • click New
chose whatever attributes you want ... here is what I did first time out.
name=adv_arm_15
target=Android 4.0.3 - API Level 15
SD card size=28 Mib
Skin=built-in
  • click Create AVD
  • highlight adv_arm_15
  • click Start
  • click Launch (take any / all defaults and wait for it to load ... maybe 30 seconds)
wait for the AVD to take input (try home or menu button - available on the above AVD)
  • execute c:\DATA\jbones\SomeApp\install_debug (installs project - .apk - on AVD)
Successful output should look like below

C:\DATA\jbones\SomeApp>echo off
using CLASSPATH ;C:\DATA\jbones\SomeApp\libs\ant-antlr.jar;C:\DATA\jbones\SomeAp
p\libs\ant-apache-bcel.jar;C:\DATA\jbones\SomeApp\libs\ant-apache-bsf.jar;C:\DAT
A\jbones\SomeApp\libs\ant-apache-log4j.jar;C:\DATA\jbones\SomeApp\libs\ant-apach
e-oro.jar;C:\DATA\jbones\SomeApp\libs\ant-apache-regexp.jar;C:\DATA\jbones\SomeA
pp\libs\ant-apache-resolver.jar;C:\DATA\jbones\SomeApp\libs\ant-apache-xalan2.ja
r;C:\DATA\jbones\SomeApp\libs\ant-commons-logging.jar;C:\DATA\jbones\SomeApp\lib
s\ant-commons-net.jar;C:\DATA\jbones\SomeApp\libs\ant-jai.jar;C:\DATA\jbones\Som
eApp\libs\ant-javamail.jar;C:\DATA\jbones\SomeApp\libs\ant-jdepend.jar;C:\DATA\j
bones\SomeApp\libs\ant-jmf.jar;C:\DATA\jbones\SomeApp\libs\ant-jsch.jar;C:\DATA\
jbones\SomeApp\libs\ant-junit.jar;C:\DATA\jbones\SomeApp\libs\ant-junit4.jar;C:\
DATA\jbones\SomeApp\libs\ant-launcher.jar;C:\DATA\jbones\SomeApp\libs\ant-netrex
x.jar;C:\DATA\jbones\SomeApp\libs\ant-swing.jar;C:\DATA\jbones\SomeApp\libs\ant-
testutil.jar;C:\DATA\jbones\SomeApp\libs\ant.jar;C:\DATA\jbones\SomeApp\libs\out
.txt;C:\DATA\tools\jdk1.6.0_12\lib\ct.sym;C:\DATA\tools\jdk1.6.0_12\lib\dt.jar;C
:\DATA\tools\jdk1.6.0_12\lib\htmlconverter.jar;C:\DATA\tools\jdk1.6.0_12\lib\ir.
idl;C:\DATA\tools\jdk1.6.0_12\lib\jawt.lib;C:\DATA\tools\jdk1.6.0_12\lib\jconsol
e.jar;C:\DATA\tools\jdk1.6.0_12\lib\jvm.lib;C:\DATA\tools\jdk1.6.0_12\lib\orb.id
l;C:\DATA\tools\jdk1.6.0_12\lib\tools.jar
using JAVA_HOME C:\DATA\tools\jdk1.6.0_12
Buildfile: C:\DATA\jbones\SomeApp\build.xml

-set-mode-check:

-set-debug-files:

install:
     [echo] Installing C:\DATA\jbones\SomeApp\bin\SomeApp-debug.apk onto default
 emulator or device...
     [exec]     pkg: /data/local/tmp/SomeApp-debug.apk
     [exec] Success
     [exec] 63 KB/s (977110 bytes in 15.081s)

installd:

BUILD SUCCESSFUL
Total time: 23 seconds
[JBONES_PROJECT_INSTALLED]
Press any key to continue . . .
  • click the apps icon (circle with 6 square dots) and find your app named SomeActivity
  • Click SomeActivity app icon ... you should see the text "Hello World, SomeActivity" which is taken directly from c:\DATA\jbones\SomeApp\res\layout\main.xml
From here you can add functionality, more Activities etc.
  • modify file c:\DATA\jbones\SomeApp\src\com\jbones\android\SomeApp\SomeActivity.java as this is the default file created by Android based on your -a during execution of [android create project]
  • modify file c:\DATA\jbones\SomeApp\res\layout\main.xml to change default text
<TextView android:text="Hello World, SomeActivity" can be changed to <TextView android:text="WHATEVER"

We hope this is useful!

jbones