Java has as many, if not more, third-party libraries than any other modern programming language. The third-party libraries I’m referring to here are the innumerable JAR files that you can include in a server or desktop Java application—the things that the Java SDKs themselves do not provide.
In the case of Android, the Dalvik virtual machine (VM) at its heart is not precisely Java, and what it provides in its SDK is not precisely the same as any traditional Java SDK. That being said, many Java third-party libraries still provide capabilities that Android lacks natively, and therefore may be of use to you in your project (if you can get them to work with Android’s flavor of Java).
This chapter explains what it will take for you to leverage such libraries and the limitations on Android’s support for arbitrary third-party code.
Not all available Java code will work well with Android. There are a number of factors to consider, including the following:
One trick for addressing some of these concerns is to use open source Java code, and actually work with the code to make it more Android-friendly. For example, if you’re using just 10% of the third-party library, maybe it’s worthwhile to recompile the subset of the project to be only what you need, or at least to remove the unnecessary classes from the JAR. The former approach is safer, in that you get compiler help to make sure you’re not discarding some essential piece of code, although it may be quite tedious to do.
You have two choices for integrating third-party code into your project: use source code or use prepackaged JARs.
If you choose to use source code, all you need to do is copy it into your own source tree (under src/
in your project), so it can sit alongside your existing code, and then let the compiler perform its magic.
If you choose to use an existing JAR, perhaps one for which you do not have the source code, you will need to teach your build chain how to use the JAR. First, place the JAR in the libs/
directory in your Android project. Then, if you are using an IDE, you probably need to add the JAR to your build path. (Ant will automatically pick up all JARs found in libs/
.)
Unlike other mobile device operating systems, Android has no restrictions on what you can run on it, so long as you can do it in Java using the Dalvik VM. This includes incorporating your own scripting language into your application, something that is expressly prohibited on some other devices.
One possible Java scripting language is BeanShell (http://beanshell.org
). BeanShell gives you Java-compatible syntax with implicit typing and no compilation required.
To add BeanShell scripting, you need to put the BeanShell interpreter’s JAR file in your libs/
directory. Unfortunately, the 2.0b4 JAR available for download from the BeanShell site does not work out of the box with the Android 0.9 and newer SDKs (perhaps due to the compiler that was used to build it). Instead, you should probably check out the source code from Subversion and execute ant jarcore
to build it, and then copy the resulting JAR (in BeanShell’s dist/
directory) to your own project’s libs/
. Or, just use the BeanShell JAR that accompanies the source code for this book, up in the Java/AndShell
project.
From there, using BeanShell on Android is no different than using BeanShell in any other Java environment:
Interpreter
class.Interpreter#set()
.Interpreter#eval()
to run the script and, optionally, get the result of the last statement of the script.For example, here is the XML layout for the world’s smallest BeanShell IDE:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/eval"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Go!"
/>
<EditText
android:id="@+id/script"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:singleLine="false"
android:gravity="top"
/>
</LinearLayout>
Couple that with the following activity implementation:
package com.commonsware.android.andshell;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import bsh.Interpreter;
public class MainActivity extends Activity {
private Interpreter i=new
Interpreter();
@Override
public void
onCreate(Bundle icicle) {
super.
onCreate(icicle);
setContentView(R.layout.main);
Button btn=(Button)
findViewById(R.id.eval);
final EditText script=(EditText)
findViewById(R.id.script);
btn.
setOnClickListener(new View.
OnClickListener() {
public void
onClick(View view) {
String src=script.
getText().
toString();
try {
i.
set("context", MainActivity.this);
i.
eval(src);
}
catch (bsh.EvalError e) {
AlertDialog.Builder builder=
new AlertDialog.
Builder(MainActivity.this);
builder
.
setTitle("Exception!")
.
setMessage(e.
toString())
.
setPositiveButton("OK", null)
.
show();
}
}
});
}
}
Compile and run it (including incorporating the BeanShell JAR as mentioned earlier), and install it on the emulator. Fire it up, and you get a trivial IDE, with a large text area for your script and a big Go! button to execute it, as shown in Figure 24–1.
Figure 24–1. The AndShell BeanShell IDE
import android.widget.Toast;
Toast.
makeText(context, "Hello, world!", 5000).
show();
Note the use of context
to refer to the activity when making the Toast
. That is the global set by the activity to reference back to itself. You could call this global variable anything you want, as long as the set()
call and the script code use the same name.
Click the Go! button, and you get the result shown in Figure 24–2.
Figure 24–2. The AndShell BeanShell IDE, executing some code
And now, some caveats:
READ_CONTACTS
permission, expect any BeanShell scripts your application runs to have the same permission. (Permissions are covered in Chapter 28.)As noted earlier, not all Java code will work on Android and Dalvik. Here are some examples:
In all these cases, if you have a compiled JAR to work with, you may not encounter problems at compile time, but only when running the application. Hence, where possible, it is best to use open source code with Android, so you can build the third-party code alongside your own and find out about difficulties sooner.
Since this chapter covers scripting in Android, you may be interested to know that you have options beyond embedding BeanShell directly in your project.
Some experiments have been conducted with other JVM-based programming languages, such as JRuby and Jython. At present, their support for Android is incomplete, but progress is being made.
Additionally, the Android Scripting Environment (ASE), available from the Android Market, allows you to write scripts in Python and Lua, to go along with BeanShell. These scripts are not full-fledged applications and, at the time of this writing, are not really distributable to others. Also note that ASE is not precisely designed to extend other applications, though it can be used that way. But if you want to do on-device programming, ASE is probably the best answer. For more information about ASE, see its project page at http://code.google.com/p/android-scripting/
.