30 April, 2012

Android Library Reuse

Well, it took me some time, but I finally uncover my original findings concerning creating an Android reuse library. Examples seem tough to come-by, so I'll post what I discovered. The overall objective is to define a reuse package that contains common source and resources. For the sake of this discussion, our reuse package will be defined as com.abc.lib, our sample project utilizing the library packaged as com.abc.sample01; First, let's create our reuse library project:

$ android create lib-project --name Lib --target 4 --path Lib --package com.abc.lib

Next, populate the source with library package contents:

$ mkdir -p Lib/src/com/abc/lib
$ cat LogUtils.java 
package com.abc.lib;

public class LogUtils {
  static public void Log (String msg) {
  }
}
$ cp ./LogUtils.java Lib/src/com/abc/lib

Building the library results in a JAR file located in bin.

/var/tmp/temp/Lib$ ant debug
Buildfile: /var/tmp/temp/Lib/build.xml

-set-mode-check:

-set-debug-files:

-set-debug-mode:

-debug-obfuscation-check:

-setup:
     [echo] Gathering info for Lib...
    [setup] Android SDK Tools Revision 16
    [setup] Project Target: Android 3.0
    [setup] API level: 11
    [setup] Project Type: Android Library
    [setup] 
    [setup] ------------------
    [setup] Resolving library dependencies:
    [setup] No library dependencies.
    [setup] 
    [setup] ------------------
    [setup] 
    [setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.

-build-setup:
     [echo] Creating output directories if needed...
    [mkdir] Created dir: /var/tmp/temp/Lib/bin
    [mkdir] Created dir: /var/tmp/temp/Lib/bin/res
    [mkdir] Created dir: /var/tmp/temp/Lib/gen
    [mkdir] Created dir: /var/tmp/temp/Lib/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...

-pre-compile:

-compile:
    [javac] Compiling 2 source files to /var/tmp/temp/Lib/bin/classes
     [echo] Creating library output jar file...
      [jar] Building jar: /var/tmp/temp/Lib/bin/classes.jar

-post-compile:

-obfuscate:

-dex:
     [echo] Library project: do not convert bytecode...

-crunch:
   [crunch] Crunching PNG Files in source dir: /var/tmp/temp/Lib/res
   [crunch] To destination dir: /var/tmp/temp/Lib/bin/res
   [crunch] Crunched 0 PNG files to u
   [crunch] pdate cache

-package-resources:
     [echo] Library project: do not package resources...

-package:
     [echo] Library project: do not package apk...

-do-debug:
     [echo] Library project: do not create apk...

debug:
[propertyfile] Creating new property file: /var/tmp/temp/Lib/bin/build.prop
[propertyfile] Updating property file: /var/tmp/temp/Lib/bin/build.prop
[propertyfile] Updating property file: /var/tmp/temp/Lib/bin/build.prop
[propertyfile] Updating property file: /var/tmp/temp/Lib/bin/build.prop

BUILD SUCCESSFUL
Total time: 2 seconds
/var/tmp/temp/Lib$ 

The contents of the JAR file can confirm the existence of the LogUtils class.
/var/tmp/temp/Lib$ jar -tf ./bin/classes.jar 
META-INF/
META-INF/MANIFEST.MF
com/
com/abc/
com/abc/lib/
com/abc/lib/LogUtils.class
Next, let's create a project that will utilize the common reuse library.

$ android create project --package com.abc.sample01 --activity Sample01 --target 2 --path Sample01
We add the library dependency by specifying the relative path to the library.
$ android update project --target 4 --path Sample01 --library ../Lib
Finally, update the project to ensure it all takes affect.
$ android update project --path Sample01
Our sample activity can reference our common library components as follows;

/var/tmp/temp/Sample01$ cat src/com/abc/sample01/Sample01.java 
package com.abc.sample01;

import android.app.Activity;
import android.os.Bundle;
import com.abc.lib.LogUtils;

public class Sample01 extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        LogUtils.Log("hello");
    }
}

Building the sample project via 'ant debug' somewhat duplicates the resources and source in the referencing project.

Kinda rough post, but it hits most of the generals.