Cómo escribir métodos nativos

J2ObjC admite la incorporación de Objective-C en métodos nativos de Java, de forma muy similar a como El JSNI de GWT admite Incorporación de JavaScript. La principal diferencia entre la incorporación de J2ObjC y GWT es que J2ObjC utiliza /*-[ y ]-*/ para delinear el código Objective-C. Esta instalación se denomina OCNI (Objective-C, interfaz nativa), para diferenciarse del JSNI de GWT.

A continuación, se muestra un ejemplo de la versión de java.lang.System de la biblioteca de emulación de JRE:

  public static native long currentTimeMillis() /*-[
    // Use NSDate
    return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
  ]-*/;

J2ObjC copia el comentario, menos los delimitadores, para crear el cuerpo del método:

  + (long long int)currentTimeMillis {
    // Use NSDate
    return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
  }

Importaciones nativas

J2ObjC analiza el código Java que se traduce para agregar directivas #import para sus dependencias. como importar el framework de la base. Sin embargo, las importaciones que solo requiera el código nativo se deben se agregan por separado. Para agregar importaciones, agrega una sección de OCNI sobre la primera clase en el archivo fuente de Java. y especificar las importaciones allí; por ejemplo:

  package my.project;

  /*-[
  #import "java/lang/NullPointerException.h"
  ]-*/

  public class Test {
    native void test() /*-[
      @throw [[JavaLangNullPointerException alloc] init];
    ]-*/;
  }

La importación es necesaria en el ejemplo anterior porque el único lugar que se hace referencia a ese tipo está en código nativo.

Bloques nativos

Dentro del cuerpo de una clase, J2ObjC busca bloques OCNI. Estos bloques se agregan sin modificar al archivo traducido, en la misma posición en relación con los miembros de la clase traducidos. Por ejemplo:

  /*-[
    static void log(NSString *msg) {
      NSLog(@"%@", msg);
    }
  ]-*/;

Esta función C se puede invocar desde cualquier método nativo que se declare después de este bloque de OCNI.

Una variante especial de este bloque de OCNI inserta código en el encabezado generado del archivo .m: /*-HEADER[...]

Cómo invocar métodos de Java desde el código nativo

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);
]-*/;

Accede a campos desde código nativo

Para leer un campo de instancia, usa myInstanceField_ o self->myInstanceField_ El sufijo final evita conflictos con los métodos con el mismo nombre.

Ten en cuenta que los campos que tienen nombres reservados tendrán dos guiones bajos. Por ejemplo: un campo llamado "id" es legal en Java, pero no en Objective C. Una vez traducidos, ese campo se llamará "id__". Por lo tanto, revisa los archivos generados si no existen campos errores del compilador.

Para escribir en un campo de instancia de objeto, usa JSNIExample_set_myInstanceField(string).

Leer un campo estático: JSNIExample_get_myStaticField()

Escribe un campo estático: JSNIExample_set_myStaticField(value).

J2ObjC y GWT

Se eligieron diferentes delimitadores para que, en la próxima versión J2ObjC, se incluyan comentarios JSNI de GWT ignorados (anteriormente, se utilizaban los mismos delimitadores que en GWT). Esto significa que una sola fuente de Java puede tienen métodos nativos con implementaciones de Objective-C, GWT y Android (a través de JNI):

  static native void log(String text) /*-{ // left-brace for JavaScript
    console.log(text);
  }-*/ /*-[                                // left-bracket for Objective-C
     NSLog(@"%@", text);
  ]-*/;

J2ObjC y Android

Las implementaciones de métodos nativos de Android y J2ObjC "simplemente funcionan", porque los métodos nativos de Android son implementada en un archivo JNI C o C++ separado. Todos los comentarios de OCNI en las clases de Java se quitan cuando compilada por javac para Android o cualquier otra plataforma de Java;