-
Notifications
You must be signed in to change notification settings - Fork 997
Writing Native Methods
J2ObjC supports embedding Objective-C into Java native methods, very similar to how GWT's JSNI supports JavaScript embedding. The main difference between J2ObjC embedding and GWT's is that J2ObjC uses /**-[ and ]-**/ to delineate Objective-C code. This facility is called OCNI (Objective-C Native Interface), to differentiate itself from GWT's JSNI.
Here's an example from the JRE emulation library's version of java.lang.System:
public static native long currentTimeMillis() /*-[
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
]-*/;
J2ObjC copies the comment, minus the delimiters, to create the method body:
+ (long long int)currentTimeMillis {
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
}
J2ObjC scans the Java code being translated to add #import directives for its dependencies, as well as importing the Foundation framework. However, any imports needed only by native code need to be separately added. To add imports, add an OCNI section above the first class in the Java source file and specify the imports there; for example:
package my.project;
/*-[
#import "java/lang/NullPointerException.h"
]-*/
public class Test {
native void test() /*-[
@throw [[JavaLangNullPointerException alloc] init];
]-*/;
}
The import is necessary in the above example because the only place that type is referenced is in native code.
Within a class body, J2ObjC scans for OCNI blocks. These blocks are added unmodified to the translated file, in the same position relative to translated class members. Here's an example:
/*-[
static void log(NSString *msg) {
NSLog(@"%@", msg);
}
]-*/;
This C function can be invoked from any native methods that are declared after this OCNI block.
Different delimiters were chosen so that in the next J2ObjC release, GWT JSNI comments will be ignored (previously the same delimiters were used as GWT). This means that a single Java source can have native methods that have Objective-C, GWT, and Android (via JNI) implementations:
public static native long currentTimeMillis() /*-{ // left-brace for JavaScript
return (new Date()).getTime();
}-*/ /*-[ // left-bracket for Objective-C
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
]-*/;
J2ObjC and Android native method implementations "just work", because Android native methods are implemented in a separate JNI C or C++ file. Any OCNI comments in Java classes are removed when compiled by javac for Android or any other Java platform.