Einführung in Java Android-DataSnap-Konnektoren für mobile Geräte

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Einführung in DataSnap-Konnektoren für mobile Geräte


Dieses Thema dient als Leitfaden für die ersten Schritte beim Erstellen und Verwenden des Android-DataSnap-Proxy für Java bei der mobilen Android-Entwicklung. Der Java-Proxy unterstützt dieselben Datentypen wie DataSnap. Zur Kapselung dieser DBX- und Delphi-Typen wurden spezielle Java-Klassen erstellt. Deren Verwendung entspricht der in Delphi.

Auf Anforderung erzeugt der DataSnap-REST-Server die zum Aufruf der Methoden auf dem Server verwendete Proxy-Klasse und sendet diese. Dies entspricht weitgehend der Proxy-Erzeugung, die Ihnen wahrscheinlich bereits vertraut ist, umfasst aber zudem das Komprimieren des Proxy und aller abhängigen Dateien sowie das Senden dieser zip-Datei an den Anforderer. Weitere Informationen über diesen Prozess finden Sie unter Einführung in DataSnap-Konnektoren für mobile Geräte.

Die Klasse DSProxy und alle Laufzeitdateien sind im Package com.embarcadero.javaandroid enthalten. Das Package hat die folgende Struktur:

Javadroidfiles.png

Hinweis: Android SDK Version 2.1 ist erforderlich.

Herunterladen der Android-Proxy-Dateien von einem DataSnap-REST-Server

Zunächst müssen Sie sich eine Kopie von Win32ProxyDownloader.exe aus dem Verzeichnis \bin Ihrer Produktinstallation beschaffen. Diese Datei und die Beschaffung einer Kopie davon wird im Thema Einführung in DataSnap-Konnektoren für mobile Geräte ausführlicher behandelt. Das Download-Programm ist ein einfaches Hilfsprogramm zur Unterstützung der Ermittlung des Proxy und anderer für die Kommunikation mit dem Server erforderlicher Dateien auf dem Server.

Für das Download-Programm müssen Sie die folgenden Parameter angeben:

  • -language (erforderlich): Gibt die mobile Plattform/Sprache des angeforderten Proxy an. Verwenden Sie für die Android-Entwicklung java_android.
  • -protocol: Gibt das zu verwendenden Verbindungsprotokoll an: http oder https. Die Vorgabe ist http.
  • -host: Gibt den Port und den Hostnamen oder die IP-Adresse an, zu der verbunden werden soll. Vorgabe ist localhost mit Port 80. Wenn ein anderer Name oder Port benötigt wird, muss der Name voll qualifiziert sein und die durch Doppelpunkt (":") getrennte Portnummer enthalten.
  • -output: Gibt den Ordner an, in den die Proxy-Dateien heruntergeladen werden sollen. Wird diese Angabe weggelassen, wird der aktuelle Ordner verwendet.

Im folgenden Beispiel werden die meisten der oben beschriebenen Parameter verwendet:

C:\Win32ProxyDownloader.exe -language java_android -host 127.0.0.1:8080 -output C:\test


Nach Ausführung des Download-Programms, werden die Android-Proxy-Dateien in den angegebenen Ausgabeordner kopiert. Dazu zählen die folgenden Dateien:

  • Statische für den Proxy erforderliche Java-Quelldateien
  • DSProxy.java, der erzeugte Proxy

Die Hauptdatei ist DSProxy.java, die die Klasse deklariert, die alle auf dem Server definierten Methoden enthält.

Nach dem Import der Dateien in Ihr Projekt sieht die Struktur folgendermaßen aus:

AndroidDemofiles.png

Verwendung der DSProxy-Klasse

Der folgende Code zeigt die vom Server erzeugte Datei DSProxy.java. Der Code enthält eine TServerMethods1-Klasse, die die Servermethoden kapselt. Der Server hat nur eine Methode (EchoString), und die Java-Klasse TServerMethods1 implementiert die Methode entsprechend. Der Proxy-Generator erzeugt den gesamten Java-Code für die Verbindung zum Server und für die Ausführung der Methoden automatisch:

 public class DSProxy {
   public static class TServerMethods1 extends DSAdmin {
     public TServerMethods1(DSRESTConnection Connection) {
       super(Connection);
     }
     
     private DSRESTParameterMetaData[] TServerMethods1_EchoString_Metadata;
     private DSRESTParameterMetaData[] get_TServerMethods1_EchoString_Metadata() {
       if (TServerMethods1_EchoString_Metadata == null) {
         TServerMethods1_EchoString_Metadata = new DSRESTParameterMetaData[]{
           new DSRESTParameterMetaData("Value", DSRESTParamDirection.Input, 
                                                DBXDataTypes.WideStringType, "string"),
           new DSRESTParameterMetaData("", DSRESTParamDirection.ReturnValue, 
                                           DBXDataTypes.WideStringType, "string"),
         };
       }
       return TServerMethods1_EchoString_Metadata;
     }
 
     /**
      * @param Value [in] - Type on server: string
      * @return result - Type on server: string
      */
     public String EchoString(String Value) throws DBXException {
       DSRESTCommand cmd = getConnection().CreateCommand();
       cmd.setRequestType(DSHTTPRequestType.GET);
       cmd.setText("TServerMethods1.EchoString");
       cmd.prepare(get_TServerMethods1_EchoString_Metadata());
       cmd.getParameter(0).getValue().SetAsString(Value);
       getConnection().execute(cmd);
       return cmd.getParameter(1).getValue().GetAsString();
     }
     
     
     private DSRESTParameterMetaData[] TServerMethods1_ReverseString_Metadata;
     private DSRESTParameterMetaData[] get_TServerMethods1_ReverseString_Metadata() {
       if (TServerMethods1_ReverseString_Metadata == null) {
         TServerMethods1_ReverseString_Metadata = new DSRESTParameterMetaData[]{
           new DSRESTParameterMetaData("Value", DSRESTParamDirection.Input, 
                                                DBXDataTypes.WideStringType, "string"),
           new DSRESTParameterMetaData("", DSRESTParamDirection.ReturnValue, 
                                           DBXDataTypes.WideStringType, "string"),
         };
       }
       return TServerMethods1_ReverseString_Metadata;
     }
 }

Der erste Schritt bei der Verwendung der Proxy-Klasse umfasst das Erstellen und Einrichten einer Verbindung zu dem Server. Die Klasse DSRESTConnection kapselt alle für die Verbindung zum Server erforderlichen Eigenschaften und Methoden. Erstellen Sie die Verbindung, und konfigurieren Sie die Eigenschaften wie folgt (Java-Code):

 import com.embarcadero.javaandroid.DSRESTConnection;
 // ...
 
 DSRESTConnection conn = new DSRESTConnection();
 conn.setHost("host");
 conn.setPort(port);
 conn.setProtocol("http");
  • Die Eigenschaft host gibt den Hostnamen oder die IP-Adresse an.
  • Die Eigenschaft port gibt den Port an, über den der Server empfängt.
  • Die Eigenschaft protocol gibt das für die Verbindung zu verwendende Protokoll an: http oder https.

Zum Remote-Aufruf der Servermethoden erstellen Sie einfach die Proxy-Klasse, übergeben die Verbindung und rufen dann die folgende Methode (Java-Code) auf:

 DSRESTConnection conn = new DSRESTConnection();
 conn.setHost("10.40.30.24");
 conn.setPort(8080); 
 
 TServerMethods1 proxy = new TServerMethods1(conn);
 String Result = proxy.EchoString("Hello, World!");

Beispiel einer Servermethode mit einem var-Parameter

Das folgende Beispiel zeigt den Code, der erzeugt wird, wenn Ihre Servermethode einen var-Parameter enthält oder mehrere Ergebnisse zurückgibt.

Dies ist der Delphi-Code für die Servermethode:

 function TServerMethods1.VarParamTest(var Value: string): string;
 begin
   Value := StrUtils.ReverseString(Value);
   Result := Value;
 end;

Und das ist der erzeugte Proxy-Code zum Aufrufen dieser Servermethode:

 private DSRESTParameterMetaData[] TServerMethods1_VarParamTest_Metadata;
 private DSRESTParameterMetaData[] get_TServerMethods1_VarParamTest_Metadata() {
   if (TServerMethods1_VarParamTest_Metadata == null) {
     TServerMethods1_VarParamTest_Metadata = new DSRESTParameterMetaData[]{
       new DSRESTParameterMetaData("Value", DSRESTParamDirection.InputOutput, 
                                            DBXDataTypes.WideStringType, "string"),
       new DSRESTParameterMetaData("", DSRESTParamDirection.ReturnValue, 
                                       DBXDataTypes.WideStringType, "string"),
     };
   }
   return TServerMethods1_VarParamTest_Metadata;
 }
 
 /**
  * @param Value [in/out] - Type on server: string
  * @return result - Type on server: string
  */
 public static class VarParamTestReturns {
   public String Value;
   public String returnValue;
 }
 
 public VarParamTestReturns VarParamTest(String Value) throws DBXException {
   DSRESTCommand cmd = getConnection().CreateCommand();
   cmd.setRequestType(DSHTTPRequestType.GET);
   cmd.setText("TServerMethods1.VarParamTest");
   cmd.prepare(get_TServerMethods1_VarParamTest_Metadata());
   cmd.getParameter(0).getValue().SetAsString(Value);
   getConnection().execute(cmd);
   VarParamTestReturns ret = new VarParamTestReturns();
   ret.Value = cmd.getParameter(0).getValue().GetAsString();
   ret.returnValue = cmd.getParameter(1).getValue().GetAsString();
   return ret;
 }

Beachten Sie bitte, dass die Methode eine Instanz von VarParamTestReturns zurückgibt. Diese Sonderklasse enthält Informationen über var-Parameter (in/out) sowie das Ergebnis.

Das folgende Beispiel zeigt, wie die Methode aufgerufen wird und die Ergebniswerte gelesen werden:

 TServerMethods1 proxy = new TServerMethods1(conn);
 VarParamTestReturns Result = proxy.VarParamTest("Hello, World!");
 System.out.println(Result.Value);
 System.out.println(Result.returnValue);

Sowohl der neue Wert des übergebenen Parameters als auch der Ergebniswert sind in der Result-Instanz enthalten. Der Wert für Result.Value ist "!dlroW ,olleH", und Result.returnValue ist "Hello, World!".

Verwenden von Heavyweight-Callbacks

Mit Heavyweight-Callbacks können DataSnap-Server fast verzögerungsfreie Benachrichtigungen an REST-Clients senden. Ein Client kann eine Callback-Funktion für ein bestimmtes, auf dem Server vorhandenes Thema registrieren. Bei Aktualisierung dieses Themas erhält der Client dann eine Benachrichtigung. Dies ist natürlich eine sehr vereinfachte Beschreibung dessen, was Heavyweight-Callbacks ausführen, sollte aber an dieser Stelle ausreichen.

Der erste Schritt bei der Verwendung von Callbacks in Ihren Anwendungen umfasst das Erstellen einer benutzerdefinierten Callback-Klasse, die von der abstrakten Klasse DBXCallback abgeleitet ist und die abstrakte Methode Execute überschreibt. Im Folgenden finden Sie eine Beispielimplementierung dieser Klasse:

 public class MyCallback extends DBXCallback { 
     public TJSONValue execute(TJSONArray params) { 
         System.out.println(params.toString());
         return new TJSONTrue();
   }
 }

Die Klasse DSClientCallbackChannelManager verwaltet die Callbacks des Client. Sie stellt Methoden für die Registrierung und Deregistrierung der Callbacks und für das Schließen einzelner oder aller Callbacks bereit. Der Konstruktor akzeptiert 3 Parameter:

  1. DSRESTConnection gibt die Serververbindungsinformationen an
  2. Ein String, der den Namen des Serverkanals enthält, bei dem die Registrierung erfolgen soll
  3. Ein String, der die ID (eindeutig für den Server) des Managers enthält

Mit dem folgenden Code wird der Manager erstellt:

 DSCallbackChannelManager manager  = 
  new DSCallbackChannelManager(conn,"chname",DSCallbackChannelManager.getNewManagerID());

Registrieren und Deregistrieren einer Callback-Funktion

Im folgenden Beispiel wird zunächst eine Callback-Funktion registriert und diese dann an denselben Kanal gesendet, bei dem sie registriert ist:

 manager.registercallback("mycb01", new MyCallback());

Dieses Beispiel registriert eine Callback-Funktion namens mycb01. Der erste Parameter für die Methode registerCallback ist eine ID für die Callback-Funktion (die ID muss für den Client-Kanal eindeutig sein). Der zweite Parameter ist die eigentliche, zu registrierende Callback-Instanz. Wenn es sich dabei um die erste Callback-Funktion handelt, die registriert wird, dann kann es sein, dass bei Rückkehr des registerCallback-Aufrufs der Callback-Manager noch nicht bereit ist, weil die Erstregistrierung asynchron ausgeführt wird. Nach dem ersten Aufruf von registerCallback kehren alle folgenden Aufrufe jedoch erst zurück, wenn die Registrierung abgeschlossen ist.

Die Verbindung bleibt geöffnet, bis Sie sie schließen oder bis sie vom Server geschlossen wird. Zum Anhalten der Verbindung können Sie die Callback-Funktion deregistrieren und den Kanal wie im Folgenden gezeigt schließen:

 manager.unregisterCallback("mycb01");
 manager.closeClientChannel();

Siehe auch