Subclassing NativeActivity makes two things possible. Firstly, we can implement an InputConnection to offer good support for IMEs, necessary for good keyboard support. Secondly, we can use it to overlay WebViews onto the NativeActivity. But to sublcass NativeActivity, we need to compile Java. To keep the toolchain go gettable, this is done with go generate. While here, check the exception after FindClass. Apparently it can throw an exception. Updates golang/go#9361. Updates golang/go#10247. Change-Id: I672545997f0c9a7580f06988a273c03404772247 Reviewed-on: https://go-review.googlesource.com/11980 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
158 lines
3.3 KiB
Go
158 lines
3.3 KiB
Go
// Copyright 2015 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build ignore
|
|
|
|
// Gendex generates a dex file used by Go apps created with gomobile.
|
|
//
|
|
// The dex is a thin extension of NativeActivity, providing access to
|
|
// a few platform features (not the SDK UI) not easily accessible from
|
|
// NDK headers. Long term these could be made part of the standard NDK,
|
|
// however that would limit gomobile to working with newer versions of
|
|
// the Android OS, so we do this while we wait.
|
|
//
|
|
// Requires ANDROID_HOME be set to the path of the Android SDK, and
|
|
// javac must be on the PATH.
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"go/format"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
)
|
|
|
|
var outfile = flag.String("o", "", "result will be written file")
|
|
|
|
var tmpdir string
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
var err error
|
|
tmpdir, err = ioutil.TempDir("", "gendex-")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
err = gendex()
|
|
os.RemoveAll(tmpdir)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func gendex() error {
|
|
androidHome := os.Getenv("ANDROID_HOME")
|
|
if androidHome == "" {
|
|
return errors.New("ANDROID_HOME not set")
|
|
}
|
|
if err := os.MkdirAll(tmpdir+"/work/org/golang/app", 0775); err != nil {
|
|
return err
|
|
}
|
|
javaFiles, err := filepath.Glob("../../app/*.java")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(javaFiles) == 0 {
|
|
return errors.New("could not find ../../app/*.java files")
|
|
}
|
|
platform, err := findLast(androidHome + "/platforms")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmd := exec.Command(
|
|
"javac",
|
|
"-source", "1.7",
|
|
"-target", "1.7",
|
|
"-bootclasspath", platform+"/android.jar",
|
|
"-d", tmpdir+"/work",
|
|
)
|
|
cmd.Args = append(cmd.Args, javaFiles...)
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
fmt.Println(cmd.Args)
|
|
os.Stderr.Write(out)
|
|
return err
|
|
}
|
|
buildTools, err := findLast(androidHome + "/build-tools")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmd = exec.Command(
|
|
buildTools+"/dx",
|
|
"--dex",
|
|
"--output="+tmpdir+"/classes.dex",
|
|
tmpdir+"/work",
|
|
)
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
os.Stderr.Write(out)
|
|
return err
|
|
}
|
|
src, err := ioutil.ReadFile(tmpdir + "/classes.dex")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
data := base64.StdEncoding.EncodeToString(src)
|
|
|
|
buf := new(bytes.Buffer)
|
|
fmt.Fprint(buf, header)
|
|
|
|
var piece string
|
|
for len(data) > 0 {
|
|
l := 70
|
|
if l > len(data) {
|
|
l = len(data)
|
|
}
|
|
piece, data = data[:l], data[l:]
|
|
fmt.Fprintf(buf, "\t`%s` + \n", piece)
|
|
}
|
|
fmt.Fprintf(buf, "\t``")
|
|
out, err := format.Source(buf.Bytes())
|
|
if err != nil {
|
|
buf.WriteTo(os.Stderr)
|
|
return err
|
|
}
|
|
|
|
w, err := os.Create(*outfile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if _, err := w.Write(out); err != nil {
|
|
return err
|
|
}
|
|
if err := w.Close(); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func findLast(path string) (string, error) {
|
|
dir, err := os.Open(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
children, err := dir.Readdirnames(-1)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return path + "/" + children[len(children)-1], nil
|
|
}
|
|
|
|
var header = `// Copyright 2015 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// File is automatically generated by gendex.go. DO NOT EDIT.
|
|
|
|
package main
|
|
|
|
var dexStr = `
|