Logik und Funktionen implementieren – von C# nach Java

Android-Entwicklung für Windows-Entwickler – eine Einführung [Teil 3]
Keine Kommentare

Die Programmierung der Logik einer Android-App erfolgt in Java. Das bedeutet, dass man sich mit der Syntax dieser Sprache auseinandersetzen muss. Zwar gelten C# und Java als miteinander verwandt, d. h. Aufbau und Wirkungsweise sind ähnlich, doch wie im wahren Leben liegen die Unterschiede im Detail. Aber auch typische Themen der App-Entwicklung wie z. B. das Ansprechen der Sensoren oder die Positionsbestimmung über GPS werden in diesem Beitrag kurz vorgestellt.

Apps bestehen auf der einen Seite aus einer gut durchdachten, aufgeräumten und hoffentlich ansprechenden Benutzeroberfläche und auf der anderen Seite aus der dahinterliegenden Fachlogik. Im vorangegangen Teil der Reihe Android für Windows-Entwickler haben wir uns mit den grundlegenden Aspekten der UI-Gestaltung vertraut gemacht. Dabei haben wir festgestellt, dass der Aufbau einer Activity in XML-Code beschrieben wird. Eine gewisse Vergleichbarkeit zum XAML-Code aus der Windows Presentation Foundation (WPF) für Windows-Apps (8.1, Phone) ist zwar gegeben, aber eine automatische Transformation ist nicht möglich. Das bedeutet: Selbst wenn schon eine Windows-App existiert, muss das UI vollständig neu aufgebaut werden. Dabei lassen sich jedoch zumindest die konzeptionellen Ansätze übertragen. Und wie sieht es hinter den Kulissen aus? Für Windows-Apps wird die Programmlogik in C# realisiert. Android setzt dagegen auf Java. Beide Sprachen gelten als einander ähnlich, verfügen über moderne Sprachmerkmale und sind objektorientiert.

Dieser Artikel möchte den Einstieg in Android-Programmierung für Windows-Entwickler so angenehm wie möglich machen; deshalb untersuchen wir zunächst wesentliche Gemeinsamkeiten und Unterschiede beider Sprachen. Dieses Ansinnen ist insbesondere immer dann von Bedeutung, wenn es gilt, bestehenden Code in das andere System zu übertragen. Im zweiten Teil dieses Artikels gehen wir zudem auf ein paar Spezifika der App-Programmierung ein. Wir untersuchen den grundsätzlichen Umgang mit den Sensoren der mobilen Geräte (Kasten: „Android für Windows-Entwickler – Ein Einstieg in drei Teilen“).

Android für Windows-Entwickler – Ein Einstieg in drei Teilen

In dieser Artikelserie präsentieren wir einen kompakten Einstieg in die Entwicklung von Apps für mobile Endgeräte mit Android-System.

Verwandt und doch verschieden

Zunächst: Beide Sprachen sind einander ähnlich. Sie verkörpern beide das objektorientierte Sprachparadigma, haben eine ähnliche Syntax und viele gleich lautende Schlüsselwörter. Die Speicherverwaltung beruht bei Java und C# auf der so genannten Garbage Collection. Belegte Ressourcen wie Speicherbereiche für Variablen und Objekte werden also im Regelfall automatisiert wieder freigegeben, wenn diese nicht mehr in Benutzung sind. Ein weiteres gemeinsames Merkmal ist das Vorhandensein von leistungsfähigen Bibliotheken. Eine Vielzahl gehört dabei bereits zum Standardumfang der Sprache bzw. des Frameworks (.NET) oder steht über Drittanbieter zur Verfügung. Für die meisten wiederkehrenden Problemstellungen existieren somit bereits Lösungsansätze. Positiv ist ebenfalls, dass externe Bibliotheken oft sowohl für die Nutzung in .NET (C#, Visual Basic), als auch in Java angeboten werden. Beispielsweise bestand die Aufgabe für das in Teil 1 vorgestellte Programmierbeispiel (das Spiel: „Schiffe versenken“) darin, einen Anbieter auszuwählen, der einen Cloud-Service für die Verwaltung der Spieldaten und zur Kommunikation mit den Benutzern (zum Beispiel das Versenden der Push-Nachrichten) zur Verfügung stellt. Die Idee sollte dabei sowohl in eine App für Windows-Systeme, als auch in eine App für Android umgesetzt werden. Also kamen nur Anbieter in Frage, die Programmierschnittstellen (API) für diese und ggf. weitere Systeme unterstützen. Nicht zuletzt sind beide Sprachen weit verbreitet, d. h. man findet viele Informationen in gedruckter Form und im Netz. Sie gelten als universelle Sprachen, die sich für viele Einsatzgebiete eignen.

Im Folgenden werden wichtige Gemeinsamkeiten und prägnante Unterschiede zwischen beiden Sprachen herausgearbeitet. Einige Inhalte können u. a. in verschiedenen Artikeln nachgelesen werden. Beginnen wir mit der Dateiorganisation.

In Java führen alle Quelldateien die Dateinamenerweiterung .java. Jede Quelldatei enthält nur eine öffentliche Klassendeklaration der obersten Ebene. Der Klassenname muss mit dem Dateinamen übereinstimmen. In C# gilt diese Beschränkung nicht. Hier können Quelldateien mehr als eine öffentliche Klassendeklaration enthalten. Außerdem muss der Dateiname nicht mit einem der Klassennamen übereinstimmen. Dennoch wird es auch für C# aus Gründen der Stilistik und Übersichtlichkeit nicht empfohlen, mehrere öffentliche Klassen in einer Datei zu definieren. Listing 1 zeigt zwei typische Header von Quellcodedateien in Java und C#.

// Java
package XYZ;
import java.io.*;
class Kunde
{
  ...
}
// C#
using System.IO;

namespace XYZ 
{
  class Kunde
  {
    // ...
  }
}

In beiden Sprachen wird zwischen Groß- und Kleinschreibung unterschieden (Case Sensitive). Grundsätzlich kennt C# alle primitiven Datentypen von Java. Darüber hinaus gibt es Erweiterungen für Zahlen ohne Vorzeichen und einen 128-Bit-Gleitkommatyp mit hoher Genauigkeit. Also besteht kein Problem in dieser Beziehung. Tabelle 1 stellt die Datentypen aus beiden Sprachen einander gegenüber. Konstanten existieren in beiden Sprachen in gleicher Verwendung.

Java Type C# Type
 boolean  bool
 java.lang.Boolean  bool?
 byte  sbyte or byte
 java.lang.Byte  sbyte?
 short  short?, ushort
 java.lang.Short  short?, ushort?
 int  int, uint, ushort
 java.lang.Integer  int?, uint?
 long  long, ulong, uint
 java.lang.Long  long?, ulong?, uint?
 short or int  ushort
 java.lang.Short or java.lang.Integer  ushort?
 int or long  uint
 java.lang.Integer or java.lang.Long  uint?
 long or BigInteger  ulong
 java.lang.Long or java.lang.BigInteger  ulong?
 char, java.lang.Character  char
 java.lang.Character  char?
 float, java.lang.Float  float
 java.lang.Foat  float?
 double  double
 java.lang.Double  double?
 java.math.BigDecimal  decimal or decimal?
 java.math.BigInteger  decimal, long or ulong?
 java.lang.String  string
 java.util.Date, java.util.Calendar  System.DateTime
 java.util.Date(rounding), java.util.Calendar(rounding)  System.DateTime
 java.util.ArrayList  System.Collections.ArrayList, System.Collections.Generic.List
 java.util.HashMap  System.Collections.Generic.Dictionary, System.Collections.Hashtable
 java.util.LinkedList  System.Collections.Generic.LinkedList
 java.util.ArrayList, java.util.Vector  System.Collections.Generic.List
 java.util.Stack  System.Collections.Generic.Stack
 java.util.Vector  System.Collections.ArrayList, System.Collections.Generic.List

Tabelle 1: Grundlegende Datentypen im Vergleich

In beiden Sprachen gibt es einen Basistyp, von dem alle anderen Klassen abgeleitet sind. Dieser lautet object in C# und Object in Java. Kommen wir zur Ablaufsteuerung: Die if-, else– und else-if-Anweisungen sind in beiden Programmiersprachen gleich. Ebenso existiert in Java und C# eine switch-Anweisung. Zu beachten ist, dass die break-Anweisung in C# Pflicht ist, während man in Java von einer Verzweigung direkt zur nächsten übergehen kann. Bezüglich der Schleifen sind bei der for-Schleife und bei den while– bzw. do…while-Schleifen keine Unterschiede vorhanden. C# kennt darüber hinaus die sehr praktische Variante der for…each-Schleife. Damit kann sehr komfortabel über alle Elemente einer Auflistung iteriert werden. Java hat erst mit Version 5 (Java 1.5) einen ähnlichen Schleifentyp eingeführt. Dieser wird als Erweiterung der for-Schleife ausgedrückt. Diese erweiterte Schleifenkonstruktion lautet in allgemeiner Notation:

for (datentyp bezeichner : ausdruck) {
  anweisung;
}

Ein Beispiel einer solchen for…each-Konstruktion ist in Listing 2 zu sehen.

import java.util.LinkedList;
public class ErweiterteForSchleife {
  public static void main(String[] args) {
    LinkedList l = new LinkedList();
    l.add("eins");
    l.add("zwei");
    l.add("drei");
    for(String s : l)
    System.out.println(s);
  }
}

Kommen wir noch zu einigen Aspekten der objektorientierten Programmierung. In Java und C# funktioniert die Vererbung auf sehr ähnliche Weise. Beide Programmiersprachen unterstützen keine Mehrfachvererbung. Um einen möglichen Mangel der Einfachvererbung (also der Ableitung von nur einer Klasse) zu beheben, gibt es in Java – ebenso wie in C# – das Konzept der Interfaces. Eigenschaften und Methoden werden auf ähnliche Art und Weise definiert; die Kurzschreibweise von C# existiert in Java (noch) nicht. Abgeleitete Klassen können Methoden mit gleichem Namen und gleicher Signatur aufweisen wie ihre Mutterklasse. Dieses als Überschreiben von Methoden bezeichnete Vorgehen wirkt in beiden Sprachen unterschiedlich. Darauf lohnt es, aufmerksam zu machen, um mögliche Fehlerquellen bereits im Voraus zu vermeiden. Es soll an einem Beispiel demonstriert werden. Blicken wir dazu zunächst in Listing 3, das C#-Code zeigt.

class A
{
  public virtual void foo()
  {
    System.Console.Write("A.foo");
  }
}
class B : A
{
  public override void foo()
  {
    System.Console.Write("B.foo");
  }
  static void Main()
  {
    A a = new B();
    a.foo();
  }
}

Was wird auf der Konsole angezeigt? Richtig: A.foo wird ausgegeben. Der Grund hierfür ist, dass C# einen Unterschied zwischen virtuellen und nicht virtuellen Methoden macht. Per Definition sind alle Methoden nicht virtuell. Daraus folgt, dass explizit angegeben werden muss, dass eine Methode virtuell ist bzw. eine virtuelle Methode überschreibt. Es ist nicht möglich, eine Methode zu überschreiben, die nicht als virtual definiert ist; ein Versuch scheitert an einem Compilerfehler. Vergisst man das Schlüsselwort override (und virtual), so gibt der Compiler eine Warnung aus, dass die neue Methode die alte verdeckt und sie nicht überschrieben wurde. Will man diesen Effekt manuell tatsächlich erreichen, kann man die Methode dafür mit dem Schlüsselwort new markieren und erreicht damit eine Neudefinition – unabhängig davon, was in der Mutterklasse definiert wurde. In Java ist das Verhalten etwas anders. Anhand des Codes in Listing 4 wird es erläutert.

class A
{
  public void foo()
  {
    System.out.print("A.foo");
  }
}
class B extends A
{
  public void foo()
  {
    System.out.print("B.foo");
  }
  public static void main(String args[])
  {
    A a = new B();
    a.foo();
  }
}

Die Ausgabe lautet in diesem Fall: B.foo. Also eine Abweichung zum Code in C#. Ist man sich unsicher, welche Methode beim Überschreiben zum Einsatz kommt, sollte man sicherheitshalber einen Breakpunkt an der betreffenden Aufrufstelle setzen und im Einzelschritt den Aufruf der Methode verfolgen. In den vorangegangenen Textabschnitten haben wir einige Aspekte beim Übergang von C# nach Java herausgearbeitet. Die Umstellung dürfte nicht allzu schwer fallen, denn viele Konzepte sind ähnlich. Grundsätzlich macht aus heutiger Sicht C# den etwas reiferen Eindruck. Die eine oder andere Formulierung gestattet es, kompakteren und – nach Ansicht des Autors – auch etwas leichter lesbaren Code zu schreiben. Dieser Eindruck ist jedoch rein subjektiv und kann durchaus dem geschuldet sein, dass dem eine jahrelange Programmierung und Anwendung in C# voraus geht. Neuere Sprachelemente wie automatisch generierte Properties verstärken jedoch diesen Eindruck.

Ganz konkret

Greifen wir dazu auf unser Beispiel der Spiele-App („Schiffe versenken“) zurück. Wir gehen davon aus, dass es Code für eine Windows-8-App gibt. Das Ziel besteht darin, diesen Code für eine zu entwickelnde Android-App nach Java zu konvertieren. In unserem Spiel sind vielfältige Algorithmen im Einsatz. Dazu gehört u. a. ein Verfahren, das die Schiffe manuell auf dem Spielfeld platziert. Dazu formulieren wir den notwendigen Algorithmus zunächst in Klartext. Das ist ein übliches Vorgehen, um sich über die Wirkungsweise bewusst zu werden. In verbaler Form kann das Platzieren der Schiffe beim Start des Spiels auf dem Spielfeld wie folgt umschrieben werden: Vorgegeben sind die jeweilige Anzahl der Schiffe einer Kategorie. Als elementare Spielregel ist darauf zu achten, dass zwischen zwei Schiffen mindestens eine Reihe/Spalte Abstand bleibt:

  1. Eine äußere Schleife wird für alle zehn Schiffe durchlaufen.
  2. Innerhalb dieser Schleife ist es das Ziel, alle möglichen Schiffspositionen zu ermitteln und zu speichern. Eine potenzielle Schiffsposition ergibt sich aus der Lage im Spielfeld (Position des ersten Felds des Schiffs), gekennzeichnet durch Angabe der Zeile und Spalte und der Ausrichtung des Schiffs, also horizontal oder vertikal.
  3. Ob eine potenzielle Schiffsposition tatsächlich in Frage kommt, ergibt sich dadurch, dass es keine Überschneidung mit einem anderen Schiff gibt und gleichzeitig ein Abstand zu allen Rändern um mindestens eine Zeile oder Spalte zu jedem anderen Schiff gegeben ist. Für diese letztgenannte Zulässigkeitsprüfung wird eine weitere Matrix in Größe des Spielfelds (matrixOfBlockedPosition) geführt. In dieser wird vermerkt, welche Felder innerhalb der Spielmatrix durch ein platziertes Schiff blockiert werden. Neben den Feldern, die das Schiff direkt belegt, sind das auch die angrenzenden Felder rund um das Schiff.
  4. Aus der Anzahl der tatsächlich in Frage kommenden Positionen wird per Zufallsmechanismus eine beliebige Position ausgewählt.
  5. Das Schiff wird platziert, d. h. es wird der Auflistung der bereits positionierten Schiffe hinzugefügt.
  6. Gleichzeitig wird auch die Matrix zur Speicherung der blockierten Felder aktualisiert.
  7. Sofern noch nicht alle zehn Schiffe platziert wurden, wird der Vorgang erneut durchlaufen, d. h. der Vorgang wird erneut ab Schritt 1 fortgesetzt.

In C# (also in einer Windows-8.1-App) sieht der Code gemäß Listing 5 aus.

public void NewRandomPositionOfShips()
{
  ships.Clear();
  CalcualteMatrixOfBlockedPositions();
  int[] sizeMatrix = { 5, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
  for (int i = 0; i < 10; i++) 
  {
    Ship ship = new Ship() { Size = sizeMatrix[i] };
    List possiblePositions = new List();
    for (int o = 0; o < 2; o++) 
    {
      for (int col = 0; col < sizeOfMatrix; col++) 
      {
        for (int row = 0; row < sizeOfMatrix; row++)         {           ShipPosition tempPosition =              new ShipPosition(col, row, (ShipOrientation)o);           if (CheckPositionOfShip(tempPosition, ship.Size))             possiblePositions.Add(tempPosition);         }       }      }     if (possiblePositions.Count > 0)
    {
      int randomPosition = random.Next(possiblePositions.Count);
      ship.Position = possiblePositions[randomPosition];
      ships.Add(ship);
      CalcualteMatrixOfBlockedPositions();
    }
  }
  CalculateShipMatrix();
}

Nun gilt es, diesen Code nach Java zu übersetzen. Das (vorläufige) Ergebnis findet sich in Listing 6. Die Abweichungen halten sich dabei in Grenzen.

package de.itfachartikel.battleship;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class GameField {
  public GameField() {
    super();
    random = new Random();
  }

  private List ships;
  private final int sizeOfMatrix = 10;
  private Random random;
  public void newRandomPositionOfShips() {
    ships.clear();
    calculateMatrixOfBlockedPositions();
    int[] sizeMatrix = { 5, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
    for (int i = 0; i < 10; i++) {
      Ship ship = new Ship();
      ship.setSize(sizeMatrix[i]);
      List possiblePositions = new ArrayList();
      for (ShipOrientation o : ShipOrientation.values()) {
        for (int col = 0; col < sizeOfMatrix; col++) {
          for (int row = 0; row < sizeOfMatrix; row++) {             ShipPosition tempPosition = new ShipPosition(col, row,                 o);             if (CheckPositionOfShip(tempPosition, ship.getSize())) {               possiblePositions.add(tempPosition);             }           }         }       }       if (possiblePositions.size() > 0) {
        int randomPosition = random.nextInt(possiblePositions.size());
        ShipPosition position = possiblePositions.get(randomPosition);
        ship.setShipPosition(position);
        ships.add(ship);
        calculateMatrixOfBlockedPositions();
      }
    }
  }

  private boolean CheckPositionOfShip(ShipPosition tempPosition, int size) {
  ...
  }

  private void calculateMatrixOfBlockedPositions() {
  ...
  }
}

Nach diesem Prinzip gilt es, bei Existenz von C#-Code die gesamte Funktionalität schrittweise in eine Java-Anwendung zu überführen. Wenn man bereits zu Beginn der App-Entwicklung weiß, dass eine Umsetzung für unterschiedliche Plattformen – und zwar in der jeweiligen primären Sprache der Plattform – geplant ist, kann man diesen Umstand bereits weitestgehend berücksichtigen. Dabei helfen gelegentlich die folgenden Vorschläge:

  1. Bei der Implementierung auf eine möglichst einfache und leicht verständliche Lösung achten.
  2. Die Verwendung möglichst generischer Programmierkonzepte ist dem Einsatz von sehr sprachindividuellen Möglichkeiten unbedingt vorzuziehen.
  3. Komplizierte Codeabschnitte wie beispielsweise Algorithmen sollten dokumentiert werden. Die Verwendung von allgemeinem Pseudocode kann hilfreich sein. Algorithmen, die in Pseudocode dokumentiert werden, können davon ausgehend sehr leicht in die Zielsprache überführt werden.
  4. Die Plattformen trennen UI und Funktionalität unterschiedlich stark voneinander. Auch die Verbindung zwischen den Schichten wird auf andere Art und Weise hergestellt. Das sehr fortschrittliche und automatisierbare Data Binding aus WPF findet sich in dieser Form in Java nicht. Auch hier ist zu Gunsten einer einfacheren Transformation mit einem möglichst generischen Ansatz zu arbeiten.
  5. Jede Codedatei sollte auch im Ausgangscode von C# nur eine öffentliche Klasse enthalten.

Abbildung 1 stellt den Prozess der übergreifenden App-Entwicklung nochmals im Zusammenhang dar. Wie gesagt, es ist umso einfacher, je früher dieser Umstand Eingang in den Entwicklungsprozess findet.

Abb. 1: Plattformübergreifende App-Entwicklung

Abb. 1: Plattformübergreifende App-Entwicklung

App-Spezifität: Wer misst Mist

Am Ende unserer Artikelserie gehen wir noch auf ein paar Besonderheiten der App-Programmierung im Zusammenhang mit der Abfrage/Programmierung der Sensoren ein. Mobile Geräte unterscheiden sich gerade in der Kommunikationsfreudigkeit mit ihrer Umwelt von stationären PCs und Notebooks. Neben dem meist vorhandenen GPS-Sensor sind oft auch noch andere Sensoren vorhanden. Es könnten Sensoren zur Messung der folgenden physikalischen Größen enthalten sein:

  • Beschleunigung inklusive Erdanziehung
  • Lineare Beschleunigung ohne Erdanziehung
  • Gyroskop (Beschleunigungs- oder Lagesensor)
  • Relative Luftfeuchtigkeit
  • Umgebungslicht
  • Magnetfeld (Kompass)
  • Schwerkraft
  • Lage
  • Luftdruck
  • Annährung
  • Rotationsvektor
  • Interne Gerätetemperatur
  • Umgebungstemperatur

Eine Auswertung über das Android-API ist möglich. Vor der Verwendung der Messwerte muss man sich zwingend mit den technischen Gegebenheiten auseinandersetzen. Man sollte die physikalischen Maße und deren Messmethode auch in Grundzügen verstanden haben, damit man weiß, was man misst. Wie gesagt, nicht alle Sensoren sind stetig vorhanden oder liefern auch wirklich brauchbare und ausreichend exakte Ergebnisse für den gewünschten Zweck. Wie fragt man nun einen Sensor aus Java ab? Dazu ist ein Zugriff auf die Klasse SensorManager notwendig. Als Erstes gilt es, herauszufinden, welche Sensoren im betreffenden Gerät vorhanden sind. Dazu betrachten wir den Code in Listing 7.

private void sensorCheck() {
  sensorManager  = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
  List sensoren  = sensorManager.getSensorList(Sensor.TYPE_ALL);
  StringBuilder sensorInfo = new StringBuilder();
  for(Sensor sensor : sensoren) {
    String str = sensor.getName();
    sensorInfo.append(str + "\n");
  }
}

Zunächst wird eine Instanz der Klasse SensorManager erzeugt. In der Liste sensoren werden alle verfügbaren Sensoren des Geräts gespeichert, welche zuvor mittels

sensorManager.getSensorList(Sensor.TYPE_ALL)

ermittelt werden. In einer Zeichenkette werden dann die Namen der einzelnen Sensoren aufgelistet, dazu wird die Liste der Sensoren mittels for-Schleife durchlaufen. Im Bedarfsfall kann dann auf die Existenz eines speziellen Sensors geprüft werden. Besonders interessant ist die Verwendung des GPS-(Global-Positioning-Systems-)Empfängers. Die exakte Ortsbestimmung bietet eine reiche Palette von Anwendungsmöglichkeiten. Zunächst wird der LocationManager ermittelt:

locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);

Auch muss dieser auf dem Gerät aktiviert sein:

if ( !locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ){
  // ggf. Hinweis, dass dieser nicht aktiv ist 
}

Mittels

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this);

legt man beispielsweise fest, dass alle 10 000 Millisekunden ein Update der Positionsdaten gesendet werden soll. Optional kann angegeben werden, dass dieses Update nur dann übermittelt wird, wenn sich die Position gegenüber der letzten Messung um einen bestimmten Mindestwert (z. B. 10 Meter) geändert hat. In diesem Fall würde man schreiben:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10, this);

Die Änderung der Position selbst wird über ein Listener-Ereignis registriert:

public void onLocationChanged(Location loc) {
  double laenge = loc.getLongitude();
  double breite = loc.getLatitude();  
}  

Die Positionsangaben werden in die Variablen laenge und breite geschrieben und können dann zum Beispiel angezeigt oder zyklisch (Tracking) gespeichert werden.

Fazit

Damit sind wir am Ende unserer dreiteiligen Serie zur Android-Programmierung für Windows-Entwickler angelangt. Die aktuellen Statistiken in Abbildung 2 bestätigen nach wie vor, dass Android im Moment die wichtigste mobile Plattform bleibt. Windows-Entwicklern mag das zwar etwas grämen, aber es hilft uns in keiner Weise.

Abb. 2: Verteilung der mobilen Plattformen, Stand 11/2014 [4]

Abb. 2: Verteilung der mobilen Plattformen, Stand 11/2014 (Quelle)

Doch vielleicht ist Rettung in Sicht. Mit Xamarin ist ein Tool auf dem Markt, das eine plattformübergreifende Entwicklung von Apps verspricht und als Programmiersprache C# verwendet. Auch eine generische Gestaltung des UI ist damit möglich. Plattformspezifische Besonderheiten bleiben aber weiterhin außen vor, sodass für viele Fragen bei der Android-Entwicklung an Java und XML für das UI (noch) kein Weg vorbeiführt.

Wir konnten das Thema App-Programmierung in Android – trotz dreiteiliger Serie – nur in ausgewählten Punkten betrachten. Es gäbe noch unendlich viel zu sagen. Als ambitionierter Windows-Programmierer ist uns der oft so kryptisch anmutende Weg über Linux und Eclipse gelungen. Unser abschließendes Fazit lautet daher: „Es geht richtig gut!“

Noch ein abschließender Hinweis: Begleitend zu dieser Serie zur App-Programmierung wird es ergänzende Informationen auf der Webseite des Autors geben. Das in Teil 2 vorgestellte Spielebeispiel wird dort weiter fortgesetzt und vorgestellt. Vorbeischauen lohnt sich also!

Mobile Technology

Mobile TechnologyDieser Artikel ist im Mobile Technology erschienen. Mobile Technology ist der Wegbegleiter für alle, die sich professionell mit der Entwicklung für mobile Devices und den Möglichkeiten, die der Markt des Mobile Business und Marketing bereithält, beschäftigen.

Natürlich können Sie das Mobile Technology über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Mobile Technology ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -