(zdia 10/2011)
The conditions of this feasibility study were
Create the projects folders
Create an Android project with something like:
$ android create project \
--package tcl.lang \
--activity JTcl \
--target 1 \
--path ~/Projekte/jtcl
To get info about your existing existing targets:
$ android list targets
Available Android targets:
id: 1 or "android-8"
Name: Android 2.2
Type: Platform
API level: 8
Revision: 3
Skins: WVGA854, WVGA800 (default), QVGA, HVGA, WQVGA432, WQVGA400
Prepare for compilation
We add an folder
assets/ and put as folder
src/ the folder
jtcl-2.0.0/src/main/java/tcl/lang of Jtcl into our development directory. We have still to put the
jtcl-2.0.0/src/main/resources/tcl/lang/library/init.tcl file into the
assets/ folder. JTcl will need it for initialization. Finally your tree hierarchy should look similar to the following:
|-- AndroidManifest.xml
|-- android
| |-- bin
| | |-- classes
| | |-- classes.dex
| | `-- jtcl.ap_
| `-- jtcl.jar
|-- assets
| `-- init.tcl
|-- bin
|-- build
|-- build.xml
|-- development.txt
|-- jtcl.properties
|-- libs
|-- proguard.cfg
|-- res
| |-- drawable-hdpi
| | `-- icon.png
| |-- drawable-ldpi
| | `-- icon.png
| |-- drawable-mdpi
| | `-- icon.png
| |-- layout
| | `-- main.xml
| `-- values
| `-- strings.xml
`-- src
`-- tcl
`-- lang
Create the binary
The file
jtcl.properties will define our local Android environment:
$ cat jtcl.properties
sdk-folder=~/Projekte/jtcl
android-tools=~/Programme/android-sdk-linux_x86/tools
android-platform=~/Programme/android-sdk-linux_x86/platforms/android-8
android-platform-tools=~/Programme/android-sdk-linux_x86/platform-tools
The file
Interpr.java in
src/tcl/lang/ has to be modified to load the
init.tcl from our
assets/ directory:
// evalResource("/tcl/lang/library/init.tcl");
evalResource("assets/init.tcl");
Then all is ready for ant which will be fed by the following
build.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Inspirations taken from the build.xml found in David Weltons "Hecl for Android":
http://www.hecl.org/
-->
<project name="JTcl for Android" default="help">
<!-- ====================================================================== -->
<!-- Build environment properties -->
<!-- ====================================================================== -->
<property name="outdir" value="android/bin" />
<property file="jtcl.properties" />
<property name="android.build" value="android/bin/classes"/>
<property name="android-jar" value="${android-platform}/android.jar" />
<property name="dx" value="${android-platform-tools}/dx" />
<property name="dex-file" value="classes.dex" />
<property name="intermediate-dex" value="${outdir}/${dex-file}" />
<property name="aapt" value="${android-platform-tools}/aapt" />
<property name="resource-dir" value="res" />
<property name="asset-dir" value="assets" />
<property name="srcdir" value="src" />
<property name="resources-package" value="${outdir}/jtcl.ap_" />
<!-- ====================================================================== -->
<!-- Help target -->
<!-- ====================================================================== -->
<target name="help">
<echo message="Possible targets: compile jar dex aapt"/>
</target>
<!-- ====================================================================== -->
<!-- Dirs target -->
<!-- ====================================================================== -->
<target name="dirs">
<echo>Creating output directories if needed...</echo>
<mkdir dir="${outdir}"/>
<mkdir dir="${android.build}"/>
</target>
<!-- ====================================================================== -->
<!-- Compilation target -->
<!-- ====================================================================== -->
<target name="compile" description="Compile the code" depends= "dirs">
<echo>bootclasspath: ${android-jar}</echo>
<javac destdir="${android.build}"
srcdir="src/tcl/lang"
source="1.5"
bootclasspath="${android-jar}" >
</javac>
</target>
<!-- ====================================================================== -->
<!-- Jar package target -->
<!-- ====================================================================== -->
<target name="jtcl-jar" depends="compile">
<echo> Building android/jtlc.jar from dir: ${android.build} ...</echo>
<jar destfile="android/jtcl.jar" basedir="${android.build}">
<manifest>
<attribute name="Main-Class"
value="tcl.lang.Shell"/>
</manifest>
</jar>
</target>
<!-- ====================================================================== -->
<!-- Dex target -->
<!-- ====================================================================== -->
<target name="dex" depends="jtcl-jar">
<echo>Converting compiled files and external libraries into ${outdir}/${dex-file}...</echo>
<apply executable="${dx}" failonerror="true" parallel="true">
<arg value="-JXmx512m" />
<arg value="--dex" />
<arg value="--output=${intermediate-dex}" />
<arg path="android/jtcl.jar" />
<fileset dir="${android-platform-tools}/lib" includes="*.jar"/>
</apply>
</target>
<!-- ====================================================================== -->
<!-- aapt target -->
<!-- ====================================================================== -->
<!--
Put the project's resources into the output package file.
We will use the folder assets to store init.tcl. An Android app has only access
to the application folders, no chance to create a folder: /tcl/lang/library/
-->
<target name="aapt" depends="dex">
<echo>Packaging resources and assets...</echo>
<exec executable="${aapt}" failonerror="true">
<arg value="package" />
<arg value="-f" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-A" />
<arg value="${asset-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
<arg value="-F" />
<arg value="${resources-package}" />
</exec>
</target>
<!-- ====================================================================== -->
<!-- Cleaning up target -->
<!-- ====================================================================== -->
<target name="clean" description="Clean the output directory">
<echo>Deleting dir: ${android.build}</echo>
<delete dir="${outdir}"/>
</target>
</project>
Preparing test
In the directory
/android/bin we will find now the executable file
classes.dex and a file
jtcl.ap_ with the resources compiled in, so we still have to add the executable to our
jtcl.ap_:
aapt add jtcl.ap_ classes.dex
The above mentioned
assets/init.tcl still has to be modified. For the moment we have no tcllib files in our assets folder so we comment out autoloading of tcllib packages:
# set dir resource:/tcl/pkg/tcllib/library
# source $dir/pkgIndex.tcl
puts "Note: No tcllib package available"
Now
jtcl.ap_ is ready for a test:
We push
jtcl.ap_ to Android assumed the folder
/data/local/bin has been already created by use of
adb shell:
$ adb push jtcl.ap_ /data/local/bin
After connection to a running Android device with
adb shell you call JTcl with its entrypoint
tcl.lang.Shell:
# dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /data/local/bin/jtcl.ap_ tcl.lang.Shell
That's it. Sure, you can use this call inside a "Terminal emulator" Android application.
The next steps will be:
- Try to get access to the Android GUI widgets by using JTcl's java::* commands
- To make a clean Android JTcl.apk which can be launched by click executing during initialization not only init.tcl but application code, e.g. in myscript.tcl