Android-Besonderheiten für Entwicklungen mit Xamarin - Teil 1

Android mit Xamarin: Die Hostplattform kennenlernen
Kommentare

Einer der gefährlichsten Irrglauben im Bereich Cross-Plattform-Entwicklung ist, dass man auch ohne Verständnis der Hostplattform erfolgreiche Applikationen erzeugen kann. Da Android spätestens dank der Übernahme von Xamarin durch Microsoft auch in den Fokus der .NET-Entwickler rückt, wollen wir nun einen Blick auf das Betriebssystem als Ganzes werfen. Schon aus Gründen der besseren Weiterverwendbarkeit unserer Ergebnisse wollen wir als Arbeits- und Forschungsumgebung Xamarin verwenden.

Diese Artikelserie wird Schritt für Schritt erklären, wie man GUIs für Android mit Xamarin Studio erstellt. Im ersten Teil widmeten wir uns zunächst der Aktualisierung von Visual Studio, dem Start der Erstellung von GUIs mit Xamarin Studio und der Fehlersuche. Im zweiten Teil geht es um Fragmentierung, Lokalisierung und Testing in Xamarin Studio. Jetzt beschäftigen wir uns mit der gesamten Hostplattform und wollen in Teil 3 die Android-Besonderheiten bei der Entwicklung mit Xamarin näher kennenlernen, bevor wir uns in Teil 4 mit den Sicherheitsvorkehrungen und Gefahren befassen.

Die folgenden Schritte basieren auf der mit Visual Studio 2015 Update 2 ausgelieferten Version der Entwicklungsumgebung. Starten sie die IDE, und erzeugen Sie ein neues Projekt vom Typ Visual C# | Android | Blank App (Android). Das leere Projektskelett bietet uns Gelegenheit für erste Gelegenheiten zur Reflektion.

Auf den Spuren von Android und Xamarin

Android ist im Grunde genommen eine Kette von parallel ablaufenden Android-Runtimes, die über eine darunterliegende Serviceschicht miteinander verbunden werden. Jede Applikation läuft dabei in ihrer eigenen Laufzeitumgebung und kann auf die Daten der anderen Apps nicht zugreifen. Die Datei AndroidManifest.xml realisiert einen Index aller im Projekt enthaltenen Elemente und ist zudem für die Zuweisung von Intents und Ereignissen an Handler verantwortlich. Die Bearbeitung des Files erfolgt unter Android Studio normalerweise manuell. Im Fall von Xamarin Studio ist die Situation komplett anders, da die Entwickler ihren Nutzern das manuelle Anpassen der Datei ersparen möchten. Wer die im Ordner Properties liegende Datei im Editor öffnet, sieht folgenden Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="SUSAndroidTest1.SUSAndroidTest1" android:versionCode="1" android:versionName="1.0">
  <uses-sdk android:minSdkVersion="16" />
  <application android:label="SUSAndroidTest1"></application>
</manifest>

Der Unterschied zu Android Studio liegt darin, dass Xamarin die Manifestdatei anhand von diversen Einstellungen zusammenbaut. Die in Visual Studio angebotene Datei wird während der Kompilation von Xamarin geparst und um die aus den Callouts erzeugten Deklarationen erweitert. Der Generator weiß dabei, welches Kindelement in welches Elternelement wandern muss.

So kommt die Deklaration der Activity beispielsweise aus der Datei MainActivity.cs, wo sich folgendes Kommando findet:

[Activity(Label = "SUSAndroidTest1", MainLauncher = true, Icon = 
"@drawable/icon")]

Wer die Ergebnisse der Arbeit des Mergingprozesses sehen möchte, öffnet die unter obj/Debug/android/AndroidManifest.xml liegende Variante des Files – die so aussieht:

<?xml version="1.0" encoding="utf-8"?>
<manifest . . .>
  <uses-sdk android:minSdkVersion="16" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Nach der Deklaration der minimal zulässigen SDK-Version, melden wir die beiden Permissions an, die für die Programmausführung notwendig sind. Android setzt auf das von JavaME und Symbian eingeführte Berechtigungssystem, um den Nutzern so zu ermöglichen, unerwünschte Applikationen anhand des Verhaltens zu erkennen und außer Gefecht zu setzen.

Im nächsten Schritt folgt das eigentliche Application-Objekt, in dem die Eigenschaften/Attribute des Programms festgelegt werden. Die Activity-Declaration besprechen wir im nächsten Abschnitt:

 <application android:label="SUSAndroidTest1" android:name="mono.android.app.Application" android:allowBackup="true" android:icon="@drawable/icon" android:debuggable="true">
  <activity android:icon="@drawable/icon" android:label="SUSAndroidTest1" android:name="md54ad7a0700598417e8970a2871168311f.MainActivity">
 <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

Weiter unten befindet sich die Deklaration eines Providers. Es handelt sich dabei um eine Art Hilfsdienst, der für die Applikation notwendige Aufgaben erledigt. Der Prozess mit dem Namen Seppuku ist für den Aufruf eines Teils der Mono-Runtime zuständig, die für die eigentliche Abarbeitung des Codes beim Debugging verantwortlich ist (Listing 1).

<provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="SUSAndroidTest1.SUSAndroidTest1.mono.MonoRuntimeProvider.__mono_init__" />
    <!--suppress ExportedReceiver-->
    <receiver android:name="mono.android.Seppuku">
      <intent-filter>
        <action android:name="mono.android.intent.action.SEPPUKU" />
        <category android:name="mono.android.intent.category.SEPPUKU.SUSAndroidTest1.SUSAndroidTest1" />
      </intent-filter>
    </receiver>
  </application>
</manifest>

Acti-was?

Nach diesem zugegebenermaßen unhandlich langen Codestück wollen wir uns der Realisierung weiterer Formulare zuwenden. Der Aufbau des Hauptformulars dient uns dabei als „Vorlage“. In der Datei MainActivity.cs findet sich folgender Code:

[Activity(Label = "ZweiteActivity")]
public class ZweiteActivity : Activity
  {
    protected override void OnCreate(Bundle savedInstanceState)
    {
      base.OnCreate(savedInstanceState);
    }
  }

Android-Ressourcen entstehen normalerweise aus xml-Dateien, die zur Laufzeit von einem Parser eingelesen und belebt werden. Im Fall unserer Activity erfolgt dies durch den Befehl setContentView, der die im Ordner /Resources/layout liegende Datei Main.axml einliest. Ihr Format wurde im vorhergehenden Artikel im Detail besprochen; weitere Informationen finden sich in der Xamarin-Dokumentation.
Klicken sie im nächsten Schritt auf Add | New Item | Activity, um ein neues Formular zu erstellen. Vergeben sie als Name ZweiteActivity. Xamarin reagiert darauf mit der Erzeugung der Datei ZweiteActivity.cs. Sie beschränkt sich im Moment auf die Initialisierung einer leeren Activity:

[Activity(Label = "ZweiteActivity")]
public class ZweiteActivity : Activity
  {
    protected override void OnCreate(Bundle savedInstanceState)
    {
      base.OnCreate(savedInstanceState);
    }
  }

Xamarin Studio zeigt sich insofern eigenwillig, als es die Erzeugung der Layoutdatei nicht automatisch im Rahmen des Anlegens einer neuen Activity erledigt. Dazu ist ein separater Aufruf von New Item erforderlich, dazu wird als Vorlage das in Abbildung 1 gezeigte Android-Layout ausgewählt.

Abb. 1: Auswahl des Android-Layouts

Abb. 1: Auswahl des Android-Layouts

Verschieben Sie das File im nächsten Schritt in den Unterordner /Resources/layout, und setzen Sie die Build Action auf AndroidResource. Das Laden der Layoutdaten erfolgt dann durch eine Anpassung von OnCreate – die Methode sieht nun so aus:

protected override void OnCreate(Bundle savedInstanceState)
{
  base.OnCreate(savedInstanceState);
  SetContentView(Resource.Layout.SecondLayout);
}

Android kennt zwei Intent-Arten

In der heutigen Handcomputerwelt sind komplexe Applikationen ohne Interprozesskommunikation undenkbar. Die einfachste Form des Austauschens von Anweisungen zwischen mehreren Android-Applikationen ist das Versenden von Intents. Als ersten Versuch zum Kennenlernen des Umgangs mit Intents erweitern wir unser Hauptformular um einen Button, der mit folgendem Code verdrahtet wird:

button.Click += delegate {
  var geoUri = Android.Net.Uri.Parse("geo:48.152015,17.084552");
  var mapIntent = new Intent(Intent.ActionView, geoUri);
  StartActivity(mapIntent);
};

Android kennt zwei Intent-Arten: Neben den direkt an eine bestimmte Klasse gerichteten Begehren gibt es auch Intents, die das Betriebssystem nach Belieben an Systemkomponenten verteilen darf. Intent.ActionView lässt Android nach einer Applikation suchen, die mit dem übergebenen URL-Schema etwas anzufangen weiß.

Wer das Programm im nächsten Schritt auf seinem Smartphone ausführt, und den Knopf anklickt, findet sich am Wohnort des Autors wieder (Abb. 2). Wenn das zum Test verwendete Telefon keine Maps-Applikation enthält, so bedankt sich Xamarin für den unausführbaren Intent mit der Fehlermeldung „No Activity found to handle Intent“.

Abb. 2: Erzeugter Kartenausschnitt

Abb. 2: Erzeugter Kartenausschnitt

Langfristige Beobachter des Mobilmarkts fragen sich an dieser Stelle, warum Android seinen Entwicklern nicht einfach ein fixes API zum Aufrufen der Maps-Applikation spendiert. Die Antwort findet sich in Geräten, wie dem BlackBerry Q10, diverse in Partnerschaft mit Yandex entwickelte Telefone oder der Amazone-Kindle-Reihe.

Durch den flexiblen Aufbau – auch die Betriebssystemkomponenten kommunizieren untereinander mit Intents – lässt sich ein Gutteil der Systemkomponenten beliebig austauschen. Neben einer hauseigenen Maps-Applikation kann man beispielsweise auch einen hauseigenen Launcher erzeugen, indem man die betreffenden Intents abfängt.

Um nun wieder zu unserer Applikation zurückzukehren, wollen wir das zweite Formular aktivieren. Dazu ist abermals ein Button im Hauptformular erforderlich, der nun mit folgendem Code verdrahtet wird:

button.Click += delegate {
 var activity2 = new Intent(this, typeof(ZweiteActivity));
  StartActivity(activity2);
}

Im Vergleich zum vorigen Beispiel fällt hier vor allem die geänderte Deklaration des Intents auf: Er bekommt nun einen Verweis auf die für die Ausführung zuständige Klasse.

Xamarin im Videotutorial

entwickler.tutorialsIn unserem entwickler.tutorial Einstieg in Cross-Plattform-App-Development mit Xamarin zeigt Jörg Neumann, wie Xamarin funktioniert und wie Sie das Maximum aus der Plattform herausholen können. Wer sich jetzt anmeldet, sichert sich das 3-in-1 Gratistutorial – und kann das erste Kapitel des Tutorials kostenlos sehen!

Schmackhafte Intents

Als nächste Aufgabe wollen wir das zweite Formular von außen heraus ansprechbar machen. Dazu ist folgende Änderung in der Deklaration der Activity notwendig:

[Activity(Label = "ZweiteActivity", Exported = true)]
public class ZweiteActivity : Activity
{
  protected override void OnCreate(Bundle savedInstanceState)
  {
    . . .
  }
}

Activities sind in Android normalerweise „privat“: die Deklaration im Manifest macht sie nicht für Drittanbieterapplikationen ansprechbar. Das Setzen des Exported-Attributs weist das System darauf hin, dass dieser Schutz hier nicht notwendig ist. Nach der erfolgreichen Neukompilierung des Objekts findet sich in der erzeugten Manifestdatei der korrekte Wert für Exported.

Als nächsten Schritt können Sie eine beliebige Android-Applikation erzeugen, die das betreffende Intent abfeuert. Obwohl wir diese Arbeit theoretisch auch in Android Studio oder Qt erledigen könnten, wollen wir hier eine weitere Xamarin-Applikation erzeugen. Sie basiert auf dem schon hinreichend besprochenen Projektskelett, das – wie im Fall des Kartenanzeigers – um einen Button zu erweitern ist. Dieser wird sodann um folgendes Code-Snippet ergänzt:

button.Click += delegate {
  Intent intent = new Intent();
  intent.SetComponent(new ComponentName("SUSAndroidTest1.SUSAndroidTest1", "SUSAndroidTest1.SUSAndroidTest1.ZweiteActivity"));
  StartActivity(intent);
};

Android-Applikationen sind – ganz wie klassische Java-Programme – in Paketen untergebracht. Das „Materpaket“ der jeweiligen Applikation findet sich im Beginn der Manifestdatei. ComponentName nimmt zwei Parameter entgegen: Neben dem Paketnamen der Applikation ist auch der voll qualifizierte Name der aufzurufenden Activity erforderlich.

Im vierten und letzten Teil der Artikelserie befassen wir uns mit Sicherheitsvorkehrungen und Gefahren in Xamarin.

Windows Developer

Windows DeveloperDieser Artikel ist im Windows Developer erschienen. Windows Developer informiert umfassend und herstellerneutral über neue Trends und Möglichkeiten der Software- und Systementwicklung rund um Microsoft-Technologien.

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

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -