Android on the Go
First, Some History
The Go programming language was first released by Google as an open source project in late 2009 as “an attempt to combine the ease of programming of an interpreted, dynamically typed language with the efficiency and safety of a statically typed, compiled language” (https://golang.org/doc/faq#creating_a_new_language). Originally designed as a “systems” language, it has become popular in a number of areas, including containers (Docker, Kubernetes), databases (CockroachDB, InfluxDB), and platform as a service (PaaS) (Deis, Flynn) systems. Within a short time, developers started to use the language for applications that lived closer to the user, first for the server-side of web applications and native desktop applications. Now, contributors to the Go language are trying to bridge the gap from server/desktop computing to mobile with a new tool (built with Go) called gomobile (https://golang.org/x/mobile). Gomobile can compile Go code into applications or libraries for both Android and iOS. This post will discuss the capabilities and benefits of using Go to build a native library for Android.
There have been several attempts to build frameworks that bridge the gap between the two major mobile computing platforms, and up until this point they have tried to provide a complete solution for writing applications on Android and iOS. Projects like Apache Cordova and Xamarin took the same “write once, run anywhere” philosophy of Java, and each had varying levels of success when they first came out. However, it is now understood that, while the capability to build these types of applications exists, the quality of the application was significantly degraded when compared to applications built with the native tools of that platform. Gomobile, and, more specifically, the gomobile bind feature, takes a different approach, providing a way to run a native library on Android and iOS and leaving the view and gui components to code native to the platform. This way, you can still save significant amounts of work by writing your models and business logic in Go and still have your application look and feel native to the platform.
Gomobile Bind, the Basics
So what is possible with with a native library written in Go designed to run on both Android and iOS? I will be demonstrating its capabilities on Android. If you want to follow along on your own machine, you can get setup with the instructions at the end of this article.
First, we have the basics. Anything exported (starts with a capital letter) in the Go library is available to the application code. This is currently limited to signed integers and floats, strings, booleans, and byte arrays/slices.
This expands to functions and structs as well:
A note about functions: due to language restrictions in Java, a function may only return a single value unless a second return value is an error. In the resulting Java code that is generated from building the gomobile library, we see the function will return the value and declare that it throws a generic exception.
This can be easily remedied by wrapping all of your return values inside a struct. If you do return a struct from your function, the return value must be a pointer to the returned struct. Again, my guess would be that this is due to Java language restrictions since all objects in Java are passed by reference. Finally, we can also export methods on our structs.
While basic variables, functions, and structs are certainly useful, they aren’t that exciting. One interesting capability of a native library built in Go is the use of interfaces. You can define an interface in Go and implement the interface in Java. The resulting implementation can then be passed as a parameter to a function or method defined in Go that accepts the interface as an argument. Gomobile libraries also allow for features that are not possible in Java, such as defining closures. The closure can then be called by Java, as long as it is attached as a property of a struct.
Go has the capability of calling C functions directly, and, in turn, this is also possible in gomobile. This is the mechanism that is used to allow gomobile code to access a few of the sensors found on most mobile devices, like the gyroscope. This has implications for making it easier to use native C libraries in mobile applications by avoiding the need to write JNI-specific code in your C library.
Hopefully, this has whet your appetite to try using Go in your next mobile project. I think the advantages are pretty large when you consider that you can use the same models and business logic across just about every major application platform in existence today. This saves time while still allowing you to write platform-specific code to present your application in a way that feels native to the platform your application is presented on.
Steps to get started:
- Install go (https://golang.org/doc/install) make sure to install/link to /usr/local/go
- $ go get golang.org/x/mobile
- $ go get github.com/alittlebrighter/testsdk
- Clone the example Android project at https://github.com/alittlebrighter/GoMobileExample
- Run Android project through studio or on the command line with “gradle installDebug”.