OpenAphid-Engine for Android v0.1.5 supports exposing Java methods as JavaScript functions, which is helpful for integrating 3rd-party services into games. The binding APIs are similar to its iOS version.

How to Expose Java Methods to JavaScript

Any public Java methods with supported return type and parameter types, can be exposed as JavaScript functions via @AphidJSFunction annotation. An instance with exposed methods can be injected into JavaScript engine as a plain JavaScript object by using AphidRenderer.setScriptBinding(String name, Object bindingObject, boolean androidOnly). The injected object will be placed inside aphid.ext or aphid.extandroid namespaces, which is managed by the androidOnly parameter.

Example of @AphidJSFunction

1
2
3
4
5
6
7
8
9
10
public class BindingTest4 {	
	@AphidJSFunction(name="add", isInUIThread=true)
	public int addInMainThread(int i1, int i2) {
		UI.assertInMainThread();
		return i1 + i2;
	}
}

//in onCreate() method of AphidActivity
glSurfaceView.getAphidRenderer().setScriptBinding("test4", new BindingTest4(), false);

The snippet above injects an instance of Java class BindingTest4 to JavaScript as aphid.ext.test4. Its method addInMainThread() can be accessed via aphid.ext.test4.add() in JavaScript.

The AphidJSFunction annotation supports two optional element-value pairs: name and isInUIThread. name declares a custom function name to JavaScript, the Java method name is used if it’s not specified; isInUIThread controls the thread to invoke the Java method, its default value is false. In OpenAphid-Engine for Android, JavaScript runs inside the GL thread. Setting isInUIThread to true makes the Java method run inside the UI thread; the execution of JavaScript is blocked in the GL thread until the Java method returns from the UI thread.

Type Conversion of Return Value from Java to JavaScript

Java JavaScript
void undefined
null null
boolean bool
primitive numeric types
(short, char, int, long, float, double)
number
String string
List array
Map object

Type Conversion of Parameter Value from JavaScript to Java

JavaScript Java
undefined null
null null
number corresponding primitive numeric type
string String
array List
object except array Map

Strict type checking is performed during conversion, which throws a JavaScript exception if the types are mismatched.

Integration with Google Analytics in Boilerplate-Android

Let’s illustrate how to integrate Google Analytics SDK into OpenAphid-Engine for Android. All source codes can be found in the Boilerplate-Android project.

After adding Google Analytics Android SDK into our project as described in its official document, we create a Java class GoogleAnalyticsBinding to bridge JavaScript and Google Analytics SDK. GoogleAnalyticsBinding makes the exposed functions have identical signatures as its iOS version, which enables the same script file(main.js) to run on both platforms.

1
2
3
4
5
6
7
8
9
10
11
public class GoogleAnalyticsBinding {
	//...

	@AphidJSFunction(isInUIThread = true, name = "setCustomVariableForScope")
	public void setCustomVariable(int index, String name, String value, int scope) {
		GoogleAnalyticsTracker.getInstance()
				.setCustomVar(index, name, value, scope);
	}

	//...
}

Then we can inject an instance into JavaScript namespace aphid.ext as what we do in iOS version:

1
2
3
4
5
glSurfaceView.getAphidRenderer().setScriptBinding(
	"gat", 
	new GoogleAnalyticsBinding(), 
	false	//place inside aphid.ext namespace
	);

Now all Google Analytics APIs can be accessed by the same JavaScript functions inside aphid.ext.gat on both iOS and Android.

That’s all for this tutorial. We’re working on OpenAphid-Engine for Android v0.2, which implements XMLHttpRequest APIs as what we already have in iOS version.