Freitag, 21. Februar 2014

Google Cloud Endpoints - Verstärkung für Android Apps (Teil 1)

Auch wenn Smartphones heute teilweise sehr leistungsstark sind, berücksichtigt der vorausschauende Entwickler, dass seine Apps auch auf schmalbrüstigen Targets laufen können. Aufgaben, die die begrenzten Ressourcen des Smartphones strapazieren, sollten daher nicht lokal ausgeführt werden. Selbst wenn die App auf einem Boliden installiert ist: Die Bandbreite des Netzwerkes ist außerhalb der Ballungsräume oft dürftig. Apps, die viele Daten bewegen, laufen dann nicht flüssig und verhageln die User Experience. Die Lösung besteht darin, Services auf Servern über das Internet bereit zu stellen und sie bei Bedarf abzurufen.

Services können mit Hilfe verschiedener Protokolle und Programmiermodelle implementiert werden. Bisher gab es keinen Königsweg und man musste sich in eine der Technologien einarbeiten. Hier soll gezeigt werden, wie man mit vergleichsweise einfachen Mitteln Services in seine App integrieren kann, die kostenlos in der Infrastruktur von Google gehostet werden. Die Software wird mit Hilfe von Eclipse-Plugins entwickelt. Die ganze Vorgehensweise ist sehr homogen: Die Eclipse- und die Java-Welt werden nicht verlassen. Es wird vorausgesetzt, dass bereits grundlegende Kenntnisse in der Entwicklung mit Android vorliegen.


Einige Werkzeuge

Google bietet seinen Kunden die App Engine als Plattform für gehostete Web-Anwendungen und Cloud Endpoints. Die Arbeit mit der App-Engine wird durch ein Eclipse-Plugin erheblich vereinfacht. Um das Plugin zu nutzen, benötigen wir Java 7.

Außerdem hat es sich bewährt für die Android-Entwicklung - insbesondere wenn man zusätzliche Plugins nutzt - eine eigene Eclipse-Installation zu verwenden. Hier gibt es ein vorkonfiguriertes Paket, das Eclipse und das Android-Plugin enthält.

Bei der Installation des Plugins für die App Engine folgen wir der Beschreibung von Google

Zwei neue Projekte

In der gewohnten Weise nutzen wir Eclipse, um ein Android Application Project namens 'Artists' anzulegen. Im Wizard akzeptieren wir alle Vorgaben. Die Schnittstelle für unsere Services erzeugen wir, indem wir - wie abgebildet - mit einem rechten Mausklick auf dem Projekt den Menüpunkt Google und dort den Punkt 'Generate App Engine Backend' auswählen. Sollte dieser Menüpunkt nicht vorhanden sein, ist vermutlich die Installation nicht korrekt. Wurde Java 7 wirklich installiert und von Eclipse erkannt?





Die Auswahl des Menüs führt uns zu einem weiteren Wizard. Hier lassen wir die Felder 'API Key' und 'Project Number' frei. Diese sind für die Arbeit mit den Google Cloud Messages vorgesehen, die wir hier nicht nutzen. 




Anschließend sehen wir in unserem Package Explorer ein neues Projekt namens 'Artists-AppEngine'. Es enthält die Demo-Klassen DeviceInfo, EMF, MessageEndpoint, DeviceInfoEndpoint und MessageData.
Dieses Projekt kann in einem der Application-Server ausgeführt werden, die es in der Enterprise Java Welt gibt. Im Plugin ist bereits Jetty enthalten und wir können das Projekt sofort starten: Rechter Mausklick auf das App Engine Projekt, 'Run As' und 'Web Application' wählen. 

Die erste Begegnung

Wenn man beim Start des Servers die Eclipse-Console beobachtet, sieht man verschiedene URLs, unter denen der Server erreichbar ist. Bei mir ist das etwa

Der Inhalt der Admin-Seite sagt uns jetzt noch nichts. Viele interessanter ist das Verzeichnis der definierten Services des Projektes:

Wir haben - in unserem Fall - zwei verschiedene APIs, wobei jede wieder mit eigenen Funktionen ausgestattet ist. Wenn wir etwa die deviceinfoendpoint API im Browser betrachten und parallel dazu die öffentlichen Methoden der Klasse DeviceInfoEndpoint im Package Explorer von Eclipse,  so sehen wir, dass diese übereinstimmen. Die Services, die wir im API-Explorer sehen, wurden als Demo bei der Erzeugung des Projektes angelegt. Beide sind etwas komplexer; wir tauchen nicht weiter ein, löschen alle fünf Klassen und behalten das Gerüst unseres Projektes.

Eigene Services

Wir definieren einen neue API, die uns mit dem Namen und den Gründungsdaten einiger Pop-Bands versorgt.

public class Band {
  private String name;
  private int founded;

  public Band() {
    super();
  }
  public Band(String name, int founded) {
    super();
    this.name = name;
    this.founded = founded;
  }

  public int getFounded() {
    return founded;
  }

  public String getName() {
    return name;
  }

  public void setFounded(int founded) {
    this.founded = founded;
  }

  public void setName(String name) {
    this.name = name;
  }
}

Die Klasse Band ist der Datentyp, mit dem unsere Services arbeiten. Dies ist eine Einschränkung bei der Arbeit mit den Cloud Endpoints: Die Parameter und Rückgabewerte unserer Service-API müssen dem JavaBean-Standard  genügen. Tatsächlich ist dies keine funktionale Einschränkung. Soll ein Service beispielseise zwei Zahlen addieren, stellt die zugehörige Bean einfach die Methoden 

void setV1(int v) 
void setV2(int v) 
int getSum()

zu Verfügung.

In der Klasse Band sind nur die Daten definiert, die zwischen Backend und Android App transportiert werden. Wir definieren jetzt die eigentliche Service-API:

@Api(name = "bandsService", version = "v1")
public class BandsAPI {
  private static ArrayList<Band> bands = new ArrayList<Band>();

  static {
    bands.add(new Band("The Beatles", 1960));
    bands.add(new Band("The Doors",1965));
  }

  public Band getBand(@Named("id") Integer id) {
    return bands.get(id);
  }
}

Die Annotationen sorgen dafür, dass der Web-Container die Klasse BandsAPI unter dem Namen bandsService bereitstellt. Der Service besteht aus den öffentlichen Methoden der Klasse. In unserem Beispiel ist dies die Methode getBand, deren Parameter unter dem Namen id öffentlich gemacht wird. Übergibt man 0 ergeben sich die Beatles, bei 1 die Doors. Es ist gibt noch viele weitere Möglichkeiten, um die Klasse zu annotieren.

Der Service wird ausprobiert

Unser Jetty-Server sollte bei fehlerfreiem Code von selbst durchstarten. Ansonsten wir den Neustart manuell. Werfen wir jetzt im API-Explorer einen Blick auf unseren eigenen Service:

Als angenehmes Feature bietet der Server die Möglichkeit einfache Tests im Browser durchzuführen: Wählen wir die API bandsService und anschließend bandsService.bandsAPI.getBand, so können wir Werte für den Parameter id einsetzen und das Ergebnis verifizieren:



Wie geht es weiter?

Dieser Beitrag hat gezeigt, wie man einfache Services entwickeln kann. Im jetzigen Stadium nutzen sie uns aber noch wenig. In weiteren Beiträgen sehen wir, wie wir die Dienste in die Android App einbinden, sie vom lokalen Server in die Infrastruktur von Google deployen und mit einer Datenbank verbinden können.

Keine Kommentare:

Kommentar veröffentlichen