mobile apps by pure go with reverse binding
TRANSCRIPT
Mobile Appsby Pure Gowith Reverse Binding
GopherCon India22nd Feb. 2017
The Go gopher was designed by Renee French.The gopher stickers was made by Takuya Ueda.Licensed under the Creative Commons 3.0 Attributions license.
Slide URL: https://goo.gl/OG55gT
Slide URL: https://goo.gl/OG55gT
Who am I?
Mercari, Inc./Souzoh, Inc.
Takuya Uedatwitter: @tenntenn■ Communities
Google Cloud Platform User Group (GCPUG) TokyoGo Beginners in Tokyo, Japangolang.tokyoGo Conference in Tokyo, Japan
■ WorksDeveloping Mercari Atte in GAE/Go
2
Slide URL: https://goo.gl/OG55gT
What is this talk about?
● The Basics of Go Mobile○ Cross-compile / cgo for Android○ What is Go Mobile?○ SDK Apps and Native Apps
● Developing Android Apps in pure Go○ gomobile bind○ What is Reverse Bindings?○ Use Platform APIs from Go
3
Slide URL: https://goo.gl/OG55gT
Cross-compile
● GOOS and GOARCH○ Go can cross-compile○ GOOS indicates target OS○ GOARCH indicates target architecture
5
# Build for 32bit Windows$ GOOS=windows GOARCH=386 go build# Build for arm Linux$ GOOS=linux GOARCH=arm go build
A linux/arm binary also works on android devices.
Slide URL: https://goo.gl/OG55gT
Web server on Android Device6
Watch at Youtube Source Code
Android
Shell on Mac
adb shell
Slide URL: https://goo.gl/OG55gT
cgo
● C codes into Go codes
7
import "unsafe"/*#include <stdio.h>#include <stdlib.h>void hello(char *s) { printf("Hello, %s\n", s); }*/import "C"func main() {
str := C.CString("GopherCon India")C.hello(str)C.free(unsafe.Pointer(str))
}
Comments before import "C" would be built as C codes
Call C’s function from Go code
Slide URL: https://goo.gl/OG55gT
cgo for Android
● cgo codes also can be cross-compiled
8
$ CGO_ENABLED=1\ CC=arm-linux-androideabi-gcc\ GOOS=android\ GOARCH=arm\ GOARM=7\ go build -buildmode=pie hellocgo.go$ adb push hellocgo /data/local/tmp
$ chmod 755 /data/local/tmp/hellocgo$ /data/local/tmp/hellocgoHello, GopherCon India
GOOS should be androidwhen CGO_ENABLED is 1.
Enable cgo at cross-compiling
adb shell
PC
Slide URL: https://goo.gl/OG55gT
buildmode
● Change output formats○ archive, c-archive
■ build into C archive (.a file)○ shared, c-shared
■ build into shared library (.so file) ○ plugin
■ bulid into Go Plugin (<= Go 1.8)○ exe
■ build into executable file○ pie
■ build into PIE style executable file
9
archive and shared ignoremain package
Go can build to .so files for Android
Slide URL: https://goo.gl/OG55gT
Go Mobile
● What is Go Mobile?○ Go Mobile is a toolkit for Mobile Platform
(Android and iOS) in Go.● How Go Mobile works?
○ Go Mobile provides bindings of Android and iOS through cgo.
10
Go CJavaObj-C
JNIcgoAndroid
iOS
Slide URL: https://goo.gl/OG55gT
Go Mobile11
https://github.com/golang/mobile
Slide URL: https://goo.gl/OG55gT
Installation
● Install gomobile comand
● Initialize the build tool chain○ gomobile init initializes the build tool
chain for mobile apps.
12
$ gomobile init -v$ ls $GOPATH/pkg/gomobileandroid_ndk_root pkg_android_amd64 pkg_android_arm64 pkg_darwin_arm versionpkg_android_386 pkg_android_arm pkg_darwin_amd64 pkg_darwin_arm64
$ go get -u golang.org/x/mobile/cmd/gomobile
Slide URL: https://goo.gl/OG55gT
gomobile command
gomobile command provides sub-commands.● Sub-commands
13
bind build a library for Android and iOSbuild compile Android APK and iOS appclean remove object files and cached gomobile filesinit install android compiler toolchaininstall compile android APK and install on deviceversion print version
Slide URL: https://goo.gl/OG55gT
SDK Apps and Native Apps
Go Mobile provides two ways to develop mobile apps.
■ SDK Apps● Write common funcations in Go as a
library■ Native Apps
● Write UI and all codes in Go
14
Slide URL: https://goo.gl/OG55gT
SDK Apps and Native Apps
● SDK Apps for Android
● Native Apps for Android
15
Go
aar fileBinding Classes (Java)
Shared library (.so)
Java
UI, IAB, ...
As a librarygomobile bind
apk file
GoGoNativeActivity
Shared library (.so)UI, audio, ...
gomobile build
Slide URL: https://goo.gl/OG55gT
An Example of SDK Apps: Ivy
● Ivy big number calculator (source code)○ Interpriter for APL-like language○ Android App and iOS App use a same engine○ The engine is written in Go by Rob Pike
16
Google Play App Store
Slide URL: https://goo.gl/OG55gT
An Example of Native Apps
● Flappy Gopher○ A mobile game written in Go Mobile○ Developed by Andrew Gerrand
for Go Conference 2015 Winter○ Source Code
17
Slide URL: https://goo.gl/OG55gT
gomobile bind
● Generate an Android Archive (.aar)○ a shared library (.so) written in Go○ a JAR file which is bult Java bindings
● Develop with Android Studio Plugin○ Runs gomobile bind○ Links to a generated .aar file
19
$ gomobile bind [-target ios|android] mypkg
Slide URL: https://goo.gl/OG55gT
Contents of an AAR file20
$ gomobile bind sample$ unzip -Z1 sample.aarAndroidManifest.xmlproguard.txt
classes.jar
jni/armeabi-v7a/libgojni.sojni/arm64-v8a/libgojni.sojni/x86/libgojni.sojni/x86_64/libgojni.so
R.txtres/
Compiled Java codes
Compiled Go/C codes
Slide URL: https://goo.gl/OG55gT
Calling Go code from Java code21
BindingsJava codes
Application Codes(Java)
C codes
Go/cgo codes
JNI Generated by gomobile bind
SDK Codes(Go)
cgo
Slide URL: https://goo.gl/OG55gT
An Example of Bindings22
package samplefunc Hello() string { return "Hello" }type MyStruct struct { Str string }func (s MyStruct) MyMethod() string { return s.Str }
public abstract class Sample {// ...private Sample() {} // uninstantiablepublic static final class MyStruct extends Seq.Proxy {
public final native String getStr();public final native void setStr(String v);public native String MyMethod();// ...
}public static native String Hello();
}
Java
Go
Struct
FieldMethod
Package Function
Slide URL: https://goo.gl/OG55gT
Type restrictions
● Signed integer and floating point type● String and boolean type● Byte slice type● Any functions
○ parameter and result types must be supported types○ results are 0, 1 or 2 (2nd result must be an error
type)● Any struct type
○ all fields and methods must be supported types● Any interface
○ all methods must be supported types
23
Slide URL: https://goo.gl/OG55gT
Calling Platform API from Go
● In-app Billing○ Purchase a items in the game
● SNS connection○ Facebook, Twitter, ...
● Advertisements● Analytics
○ Google Analytics, Firebase, Facebook Analytics,...
24
These APIs are provided as Java SDK for Android
Slide URL: https://goo.gl/OG55gT
Traditional gomobile bind
● Bindings to Go from Java/Obj-C● Platform APIs can be accessed BUT...
○ Indirect way○ Needs wrappers○ Not convenient
25
A way to access directlyPlatform APIs from Go is needed!
Slide URL: https://goo.gl/OG55gT
Reverse Bindings
● Access Platform APIs from Go● Generate bindings automatically
○ Reverse direction of traditional one○ use gomobile bind
● Prposed by #16876 and #17102 (Android) (iOS)
26
Slide URL: https://goo.gl/OG55gT
Reverse Bindings27
Bindings
Java codes
Go Codes
C codes
Go/cgo codes
JNI
Generated by gomobile bind
Platform APIs(Java)
cgo
Slide URL: https://goo.gl/OG55gT
An Example of Reverse Bindings28
package pkg
import "Java/java/lang"import "Java/pkg"
type Obj struct {lang.Object
}
func (h *Obj) ToString(this *pkg.Obj) string {return "hoge"
}
● Parse import statements○ Java/* or ObjC/*
● Generate bindings automatically
corresponds java.lang package in Java
inherit java.lang.Object
Hold a Java instance
Slide URL: https://goo.gl/OG55gT
How Generate Reverse Bindings?
● Parse import statements○ Begin with Java/
● Extract class infomation by javap○ Exported fields and methods○ Dependent classes○ Implementing interfaces
● Generate bindings of all dependented classes and interfaces
29
$ javap java.lang.StringCompiled from "String.java"public final class java.lang.String implements java.io.Serializable, java.lang.Comparable<java.lang.String>, java.lang.CharSequence {
public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
public java.lang.String();....
Slide URL: https://goo.gl/OG55gT
Using Platform APIs from Go
● Example of Reverse Binding in x/mobile
30
$ cd $GOPATH/src/golang.org/x/mobile$ cd example/reverse/android$ gradle wrapper$ ./gradlew build$ cd build/outputs/apk$ adb install -r android-debug.apk
Android Studioalso can build
Slide URL: https://goo.gl/OG55gT
Use Platform APIs from Go
● Use Activity and write in life cycle of Android
31
type MainActivity struct {app.AppCompatActivitybinding databinding.ActivityMainBinding
}func (a *MainActivity) OnCreate(
this gopkg.MainActivity, b os.Bundle) {...
}func (a *MainActivity) OnDestroy(
this gopkg.MainActivity) {...
}
reverse.go
Slide URL: https://goo.gl/OG55gT
Use Platform APIs from Go
● Use data binding of Android
32
func (a *MainActivity) OnCreate(this gopkg.MainActivity, b os.Bundle) {
this.Super().OnCreate(b)db := DataBindingUtil.SetContentView(
this, rlayout.Activity_main)a.binding = ActivityMainBinding.Cast(db)a.binding.SetAct(this)
}func (a *MainActivity) GetLabel() string {
return "Hello, GopherCon India!"}
reverse.go
Slide URL: https://goo.gl/OG55gT
Use Platform APIs from Go
● Use data binding of Android
33
...<data>
<variable name="act"type="reverse.MainActivity"/>
</data><RelativeLayout ...
<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{act.label}"/>
</RelativeLayout></layout>
activity_main.xml
Slide URL: https://goo.gl/OG55gT
Summaries
● The Basics of Go Mobile○ Cross-compile / cgo for Android○ What is Go Mobile?○ SDK Apps and Native Apps
● Developing Android Apps in pure Go○ gomobile bind○ What is Reverse Bindings?○ Use Platform APIs from Go
34
Thank you! twitter: @tenntenn Qiita: tenntenn
35
Slide URL: https://goo.gl/OG55gT
Binding between Go and Java36
Package Abstruct Class
Struct Inner Class
Struct Field Getter/Setter(Native)
Method Method(Native)
Package Function Static Method
Go Java
● gomobile bind generates bindings