Aplicaciones Android con Gomobile

10 November 2016

Daniel Esteban

Video

Esta charla fue presentada en el I Meetup Gophers Murcia

Ver el video en Youtube

2

Atención

El proyecto Go Mobile es experimental. Úsalo bajo tu propio riesgo.

3

Motivación

4

Dos formas

5

Aplicaciones nativas

6

En resumen

Compilar con

$ gomobile build -target=android path/to/your/project
$ gomobile build -target=ios path/to/your/project
7

Aplicaciones SDK (de lo que esta charla trata)

8

Ventajas

9

Desventajas

10

antes de empezar

$ go get golang.org/x/mobile/cmd/gomobile
$ gomobile init # it might take a few minutes
11

Binding en acción

Código Go

package mygolibrary

func Hello(name string) string {
    return "Hello " + name + "! (from go)"
}

Código Java generado

public abstract class Mygolibrary {
    public static String hello(String name) { ... }
}

Compilar con

$ gomobile bind -target android -o mygolibrary.aar -v .
12

Más binding (structs)

Código Go

package mygolibrary

type Counter struct {
    Value int64
}

func (c *Counter) Inc() {
    c.Value++
}

func NewCounter() *Counter {
    return &Counter{}
}
13

Java API generada

public abstract class Mygolibrary {
    public static final class Counter {
        public void inc() { ... }
        public long getValue() { ... }
        public void setValue(long value) { ... }
    }

    public static Counter newCounter() { ... }
}

Usar desde Java con

Counter counter = newCounter();
counter.setValue(12345);
counter.inc();
14

Llamar a Go desde Java

mygolibrary.go

package mygolibrary

func Hello(name string) string {
    return "Hello " + name + "! (from go)"
}

MainActivity.java

import go.mygolibrary.Mygolibrary;

public class MainActivity {
    ...
    private void someJavaFunction()
    {
            String resultFromGo = Mygolibrary.hello("JAVA");
            Log.d(TAG, resultFromGo);
    }
    ...
}
15

Llamar a Go desde Java (con errores)

mygolibrary.go

package mygolibrary

func HelloWithError(name string) (string, error) {
    return "Hello " + name + "! (from go)", nil
}

MainActivity.java

    ...
    private void someJavaFunction()
    {
            try {
                String resultFromGo = Mygolibrary.helloWithError("JAVA");
                Log.d(TAG, resultFromGo);
            } catch(Exception e) { // If error != nil in Go, will enter the catch
                Log.e(TAG, e.toString());
            }
    }
    ...
16

Llamar a Java desde Go (1/3)

Creamos una interfaz en Go que será exportada (gomobile bind) a Java, posterior la tendremos que implementar en Java

mygolibrary.go

package mygolibrary

var jc JavaCallback

type JavaCallback interface {
    OneMethod()
    AnotherMethod(string)
}

func RegisterJavaCallback(c JavaCallback) {
    jc = c
}
17

Llamar a Java desde Go (2/3)

Implementar en Java nuestra interfaz

GoCallback.java

import go.mygolibrary.JavaCallback;

public class GoCallback implements JavaCallback {

    public void oneMethod() {
        ...
    }

    public void anotherMethod(String data) {
        ...
    }

}
18

Llamar a Java desde Go (3/3)

Registrar el callback (en Java)

// REGISTER CALLBACK
GoCallback gocb = new GoCallback();
Mygolibrary.registerJavaCallback(gocb);

Después de eso, ya la podemos usar desde Go

jc.OneMethod();
jc.AnotherMethod("Some string here");
19

Cómo compilar

$ gomobile bind -target android -o mygolibrary.aar -v .

En nuestro proyecto android:

android/settings.gradle

include ':app', ':mygolibrary'

android/app/build.gradle

dependencies {
    ...
    compile project(':mygolibrary')
}
20

Pero no recompila!

Si modificamos mygolibrary.aar los cambios no se añadiran

21

Pero no recompila!

Tenemos que recompilarlo (en gradle)

android/build.gradle (añadir)

repositories {
    ...
    flatDir {
        dirs "$rootDir/mygolibrary"
    }
}

android/app/build.gradle (modificar)

dependencies {
    ...
    compile (':mygolibrary@aar') { changing = true }
}
22

Historia de éxito

Password Manager para TREZOR para dispositivos Android

23

Password Manager (continuación)

(early app version)

24

Password Manager (continuación)

Cómo unir las piezas

+--------------+   async promise   +--------+  blocking call    +--------+
| REACT NATIVE +-----------------> |  JAVA  +-----------------> |   GO   |
+-------+------+                   ++----+--+                   +----+---+
        ^                           |    ^                           |
        |          events           |    |    registered callback    |
        +---------------------------+    +---------------------------+
25

¿Por qué usamos un callback?

26

Otras historias de éxito

Ivy
- Ivy es un intérprete para un APL-like language
- Escrito por Rob Pike
- Código fuente en github.com/robpike/ivy
- Google Play Store play.google.com/store/apps/details?id=org.golang.ivy

Goku
- Sudoku solver
- React-native para la UI
- Escrito por Miguel Espinoza
- Código fuente en github.com/miguelespinoza/react-goku
- Google Play Store play.google.com/store/apps/details?id=com.miguelespinoza.goku

27

Algunos trucos (basados en nuestra experiencia)

func CallThisFromJava() {
    go runThisAsync()
}
func runThisAsync() {
    /* your code here */
}
28

Notas

29

Thank you

Daniel Esteban

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)