J2ObjC 支持将 Objective-C 嵌入到 Java 原生方法中,非常类似于
GWT 的 JSNI 支持
JavaScript 嵌入。J2ObjC 嵌入和 GWT 的主要区别在于,J2ObjC 使用
/*-[
和 ]-*/
,用于描述 Objective-C 代码。此功能称为 OCNI(Objective-C)
原生接口),以便与 GWT 的 JSNI 区分开来。
以下是 JRE 模拟库版本的 java.lang.System
中的示例:
public static native long currentTimeMillis() /*-[
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
]-*/;
J2ObjC 复制注释,去掉分隔符,以创建方法正文:
+ (long long int)currentTimeMillis {
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
}
原生导入
J2ObjC 扫描正在转换的 Java 代码,为其依赖项添加 #import 指令,同时 导入基础框架不过,只要是原生代码所需的导入, 单独添加。如需添加导入,请在 Java 源文件中第一个类上方添加 OCNI 部分 并在其中指定导入例如:
package my.project;
/*-[
#import "java/lang/NullPointerException.h"
]-*/
public class Test {
native void test() /*-[
@throw [[JavaLangNullPointerException alloc] init];
]-*/;
}
在上例中有必要导入,因为引用该类型的唯一位置是 原生代码
原生屏蔽
在类正文中,J2ObjC 扫描 OCNI 块。这些块未经修改 翻译后的文件与已翻译课程成员的位置相同。示例如下:
/*-[
static void log(NSString *msg) {
NSLog(@"%@", msg);
}
]-*/;
可以从在此 OCNI 块之后声明的任何原生方法调用此 C 函数。
此 OCNI 块的特殊变体会改为在生成的头文件中插入代码
.m 文件中的值:/*-HEADER[...]
从原生代码调用 Java 方法
public native void bar(JSNIExample x, String s) /*-[
// Call instance method instanceFoo() on this
[self instanceFooWithNSString:s];
// Call instance method instanceFoo() on x
[x instanceFooWithNSString:s];
// Call static method staticFoo()
JSNIExample_staticFooWithNSString_(s);
]-*/;
从原生代码访问字段
如需读取实例字段,请使用 myInstanceField_
或
self->myInstanceField_
。尾随后缀可避免与方法冲突
使用相同名称
请注意,具有预留名称的字段将带有两个下划线。例如: 名为“id”的字段在 Java 中是合法的,但在 Objective C 中则不合法。翻译之后, 该字段将被命名为“id__”。因此,如果遇到以下情况,请检查生成的文件: 您将发现编译器错误。
如需写入对象实例字段,请使用 JSNIExample_set_myInstanceField(string)
读取静态字段:JSNIExample_get_myStaticField()
编写静态字段:JSNIExample_set_myStaticField(value)
J2ObjC 和 GWT
选择了不同的分隔符,以便在下一个 J2ObjC 版本中,GWT JSNI 注释将是 被忽略(以前与 GWT 使用相同的分隔符)。这意味着单个 Java 源代码 具有具有 Objective-C、GWT 和 Android(通过 JNI)实现的原生方法:
static native void log(String text) /*-{ // left-brace for JavaScript
console.log(text);
}-*/ /*-[ // left-bracket for Objective-C
NSLog(@"%@", text);
]-*/;
J2ObjC 和 Android
J2ObjC 和 Android 原生方法实现“恰如其分”,因为 Android 原生方法 在单独的 JNI C 或 C++ 文件中实现。在以下情况下,Java 类中的所有 OCNI 注释都会被移除: 由 javac 针对 Android 或任何其他 Java 平台编译而成。