Native Methoden schreiben

J2ObjC unterstützt die Einbettung von Objective-C in native Java-Methoden, ähnlich wie bei der JSNI von GWT unterstützt JavaScript-Einbettung. Der Hauptunterschied zwischen J2ObjC-Einbettung und GWT besteht darin, dass J2ObjC /*-[ und ]-*/, um den Objective-C-Code abzugrenzen. Diese Einrichtung wird als OCNI (Objective-C) bezeichnet. Native Interfaces), um sich von der JSNI von GWT zu unterscheiden.

Hier ein Beispiel aus der Version von java.lang.System der JRE-Emulationsbibliothek:

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

J2ObjC kopiert den Kommentar ohne die Trennzeichen, um den Methodentext zu erstellen:

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

Native Importe

J2ObjC scannt den zu übersetzenden Java-Code, um #import-Anweisungen für seine Abhängigkeiten hinzuzufügen, und als Import des Grundlagen-Frameworks. Alle Importe, die nur mit nativem Code benötigt werden, müssen jedoch separat hinzugefügt werden. Um Importe hinzuzufügen, fügen Sie in der Java-Quelldatei über der ersten Klasse einen OCNI-Abschnitt ein und die Importe dort angeben. Beispiel:

  package my.project;

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

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

Der Import ist im obigen Beispiel erforderlich, da der einzige Ort, auf den dieser Typ verwiesen wird, sich in nativen Code.

Native Blöcke

Innerhalb eines Klassentextes sucht J2ObjC nach OCNI-Blöcken. Diese Blöcke werden der übersetzte Datei an derselben Position relativ zu den übersetzten Kursteilnehmern angezeigt werden. Beispiel:

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

Diese C-Funktion kann über jede native Methode aufgerufen werden, die nach diesem OCNI-Block deklariert wird.

Mit einer speziellen Variante dieses OCNI-Blocks wird stattdessen Code in den generierten Header eingefügt. der M-Datei: /*-HEADER[...]

Java-Methoden aus nativem Code aufrufen

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

Über nativen Code auf Felder zugreifen

Um ein Instanzfeld zu lesen, verwenden Sie entweder myInstanceField_ oder self->myInstanceField_. Das nachgestellte Suffix verhindert einen Konflikt mit Methoden mit demselben Namen.

Felder mit reservierten Namen haben zwei Unterstriche. Beispiel: ein Feld namens „id“ ist in Java legal, aber nicht in Objective-C. Bei der Übersetzung erhält dieses Feld den Namen „id__“. Prüfen Sie daher bitte die generierten Dateien, gibt es „no-so-field“ Compiler-Fehler.

Verwenden Sie JSNIExample_set_myInstanceField(string), um in das Feld einer Objektinstanz zu schreiben

Statisches Feld lesen: JSNIExample_get_myStaticField()

Statisches Feld schreiben: JSNIExample_set_myStaticField(value)

J2ObjC und GWT

Unterschiedliche Trennzeichen wurden gewählt, sodass GWT JSNI-Kommentare in der nächsten J2ObjC-Version ignoriert (zuvor wurden dieselben Trennzeichen als GWT verwendet). Das bedeutet, dass eine einzelne Java-Quelle native Methoden mit Objective-C-, GWT- und Android (über JNI)-Implementierungen haben:

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

J2ObjC und Android

Nativen Methodenimplementierungen für J2ObjC und Android funktionieren einfach, da native Methoden von Android in einer separaten JNI C- oder C++-Datei implementiert. OCNI-Kommentare in Java-Klassen werden entfernt, wenn die mit Javac für Android oder eine andere Java-Plattform kompiliert wurden.