Compiling for Android SDK 1 (Part 2)

Part 1 Installing JDK1.5 and Eclipse Europa
Part 2 Generating R.java and compiling Java source
Part 3 Cross compile to JDK 1.5, convert to dex, package .apk
Part 4 Code sign .apk
Part 5 Troubleshooting and success

After spending a few hours getting Eclipse Europa working on a modern Linux install I find that the Android ADT plugin 0.8.0 has completely disappeared from the internet. Every reference I can find points to the original Google download URL, and that's long since gone. Google don't appear to have it archived anywhere. So I need to abandon the Eclipse route and compile using the command-line tools instead.

I found an old Wordpress post from 2009 that is miraculously still up that has a walkthrough for building without ADT:

How to build Android application package apk from the command line

Generate R.java using AAPT

aapt is the Android Asset Packaging Tool, this has some dependencies I need to fix:

error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory

StackOverflow helps yet again:

error while loading shared libraries: libz.so.1

`sudo apt-get install lib32z1` fixes the first error but then there's more, scrolling through the SO post I find another answer which fixes the rest `sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1` (the NCurses dependecy in the SO answer wasn't found, but it wasn't needed anyway).

I clone Phaedra into my home directory and from the sdk tools directory:

./aapt package -f -M ~/phaedra/app/src/main/AndroidManifest.xml -I android.jar -S ~/phaedra/app/src/main/res -m -J ./phaedra

Finally I get some useful errors, resource buckets aren't available in this early SDK, and mipmap was added much later too:

invalid resource directory name: /home/oppen/phaedra/app/src/main/res/drawable-mdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/drawable-anydpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/drawable-xxhdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/mipmap-xxxhdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/mipmap-mdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/mipmap-xxhdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/mipmap-xhdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/mipmap-hdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/drawable-hdpi
invalid resource directory name: /home/oppen/phaedra/app/src/main/res/drawable-xhdpi

After removing mipmap entirely, and moving a single version of each image asset into the drawable folder the next big error in the output is the use of `match_parent` in the layout widths and heights fields, in earlier Android versions this constant was called `fill_parent`. I work through further errors (`imeOptions` and `inputType` not available on EditTexts, that kind of thing).

With all these problems fixed (and after `mkdir phaedra` in the tools directory for the output destination) I now have aapt generating R.java

Compile Java source and R.java using javac

This is standard Java but we need to tell the current javac to cross compile using the old JDK1.5 install:

Java Cross-Compilation Example

Before we get to cross-compilation though we need to pass all the Phaedra projects .java files and the output R.java to javac, something like:

find ~/phaedra/ -type f -name "*.java" -print | xargs javac -cp android.jar -d phaedra_classes

That's close but we need R.java too, there probably is a one-liner to do it, but let's make a reusable bash script and incorporate the first steps too:

#!/bin/bash

echo "Oppen APK build script for Android G1/HTC Dream"

# Get arguments
# eg. ~/phaedra
projectDirectory=$1
androidJar=$2
outputDirectory="pbld_out"

# Generate R.java
echo "1. Generate Android R.java..."
rm -r "$outputDirectory"
mkdir "$outputDirectory"
./aapt package -f -M "$projectDirectory/app/src/main/AndroidManifest.xml" -I "$androidJar" -S "$projectDirectory/app/src/main/res" -m -J "./$outputDirectory"

# Compile Java source
echo "2. Finding Java source..."

rFile=$(find $outputDirectory -type f -name "*.java")
javaFiles=""
javaFiles+="$rFile "
projectFiles=$(find $projectDirectory -type f -name "*.java")
for projectFile in $projectFiles
do 
    javaFiles+="$projectFile "
done

echo "javaFiles: $javaFiles"

echo "3. Compile Java source..."
classesDirectory="$outputDirectory/classes"
mkdir "$classesDirectory"
javac $javaFiles -cp $androidJar -d $classesDirectory

At this point I'm getting more useful errors, our target SDK is the same as the build SDK, and it's the 1.0 SDK, so code like this won't work:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//...
}

I need to remove all the conditional statements that use the static generated Build class and try again. It also turns out Android SDK 1 doesn't have `onBackPressed()` in the Activity, so this block needs moving to some new UI element:

@Override
public void onBackPressed() {
    if(mercury.canGoBack()){
        String previous = mercury.goBack();
        addressEdit.setText(previous);
        go();
    }else {
        super.onBackPressed();
    }
}

But it's late, so that'll need to wait for Part 3.


© 2019 - 2021 ÖLAB
Part of a webring
view in Gemini