Go auf Android und iOS
Von Martin Bertschler am 27.10.2015
Wenn eine App für mehrere Plattformen nativ erscheinen sollen, ist es oft wünschenswert nur das native Userinterface in der Zielsprache zu schreiben und möglichst viel Business Logic nur einmal zu schreiben. Es gibt einige Programmiersprachen die dieses Problem zu lösen. Zum einen gibt es natürlich Javascript, allerdings werden Apps in denen Javascript verwendet wird eher als hybrid Apps angesehen. Eine andere Methode ist das Xamarin Framework, das C# verwendet und auch auf allen großen mobilen Plattformen verwendet werden kann. Die Variante Programme in C/C++ zu schreiben wird oft von Spiel-Frameworks verwendet, da alle Betriebssysteme Wege bieten diesen nativen Low-Level Code auszuführen.
Mit dem Release Version 1.5 der Go Programmiersprache gibt es nun eine weitere Möglichkeit Code einmal zu schreiben und auf mehreren mobilen Betriebssystemen unverändert auszuführen. Dieses Feature ist einstweilen noch experimentell, trotzdem ist jetzt ein guter Zeitpunkt um dieses Feature einmal ausprobieren. Unterstützde Plattformen sind Android auf ARMv7 Prozessoren und iOS auf ARMv8 (64bit) Prozessoren (also alle iPhones ab 5s).
Voll oder Teilweise Go App
Es gibt 2 Varianten Go in nativen iOS und Android Apps zu verwenden.
Komplette App in Go
Der erste Ansatz ist es die ganze App in Go zu schreiben. Das bedeutet allerdings auch dass die APIs limitiert sind, die portabel zwischen Android und iOS sind. Das sind zum Beispiel OpenGL, Audio, Sensor und ähnliche APIs die zum Beispiel auch für Android NDK (Native Dev Kit = C/C++ Apps). Das kann mit dem Go Build Tool erreicht werden, das das generieren der App für den User übernimmt.
Teil der App in Go
Der zweite Ansatz ist das eine normale native App für die Plattform entwickelt wird, und nur ein Teil der App als Library eingebunden wird. Dazu wird die Go Library so kompiliert dass über eine C API auf die Go Funktionen zugegriffen werden kann. In einem zweiten Teilschritt generiert das gomobile bind Tool bindings für die jeweilige Zielsprache Java oder Objective-C. Dabei gibt es einige Limitierungen der Typen die die Objekte beinhalten dürfen und Funktionen als Argumente bekommen und zurückgeben können. Zum Beispiel ist es nicht möglich Unsigned Integers zu verwenden. Da Java dafür kein Equivalent bereitstellt. Der einzige Array Typ der verwenden kann ist ein Byte Array. Arrays oder Hashmaps mit anderen Typen sind noch nicht untertützt, befinden sich allerdings in Entwicklung.
Dokumentation
Details wie komplette Apps oder Libraries programmiert werden können sind unter diesen Links zu finden:
Der Code ist hier verfügbar: github.com/golang/mobile
Allgemeine Dokumentation: Go Mobile Wiki
Dokumentation für pure Go Apps: Go App Doku
Dokumentation für Go Libraries: Go Bindings Doku
Benchmark
Für meine Projekte ist die Methode bei der ein Teil der App als Go Library eingebunden wird die interessanteste, da ich gerne Apps mit nativen User Interface Komponenten programmieren würde, aber auch möglichst viel Business Logic Code zwischen den Plattformen und eventuell auch dem Server teilen würde um ihn nur einmal programmieren und testen zu müssen. Um Go Libraries in Apps zu evaluieren Abschluss habe ich die Demoapplikationen aus dem Wiki (Link oben bei der Dokumentation) für meine Zwecke erweitert und ein paar Tests durchgeführt. Dazu haben ich im Go Code eine Funktion eingefügt die die Zahlen von 0 bis 100000 addiert und zurückgibt. Eine zweite exportierte Funktion gibt direkt die Zahl 2 zurück und ist deswegen zum testen der Latenz zwischen Objective-C/Java und Go geeignet.
Resultate
Als Testgerät wurde ein Samsung Galaxy S6 und der XCode Simulator mit einem iPhone 6s verwendet. Das erste laden der Library beim Start der Applikation benötigt ca 7-15ms. Go Code läuft so schnell wie es auf der Hardware direkt laufen würde, der einzige Overhead ist die Latenz von Calls zwischen Go und Java. Diese liegen bei ca. 30 – 100µs. Das bedeutet dass bei einer App die mit der höchsten Bildwiederholrate 60fps läuft mindestens 160 mal eine Go Funktion während der Renderingzeit eines Frames augerufen werden kann. Dabei wird allerdings noch keine wirkliche Arbeit erledigt. Für die Praxis lässt sich schließen dass die Anzahl der Calls zwischen den Sprachen möglichst klein gehalten werden soll, im Idealfall also nur 1 Call pro Frame. Obwohl es sich hier um eine nicht vernachlässigbare Latenz handelt, sind Go Libraries ein sinnvoller Weg um den gleichen Code auf Android, iOS und dem Server/Desktop zu verwenden.
The comments are closed.