LoginSignup
30
29

More than 5 years have passed since last update.

GoAndroidでʕ ◔ϖ◔ʔGo~

Last updated at Posted at 2013-12-02

はじめに

3日日担当の@ladicleです
タイトル通りAndroidのアプリ上でGoを動かそうと思います
とは言っても一から作るのではなく
eliasnaurさんが書かれたパッチを使用していきます

GoとAndroid

御存知の通り、AndroidのアプリはJavaで書かれていますので
そのままGoを動かすことはできません
というわけで、ネイティブライブラリ(.so)にしてアプリに埋め込みます

アプリじゃなくてルート取って動かせればいいよって方はこちら
パッチの話はここらへん参照。

環境

OS: Ubuntu 13.10 desktop amd64

昨日のRelease1.2で、OSXでもできるようになりました!!!

必要なもの

  • Git
  • Mercurial
  • JDK7
  • Ant

導入

1 SDK

SDKをDL。任意の場所に解凍してパス設定

export ANDROID_HOME="$HOME/Develop/Android/SDK"
2 NDK

NDKをDL。任意の場所に解凍してパスを設定

export NDK="$HOME/Develop/Android/NDK"

下記のコマンドでNDKtoolchainの生成

$NDK/build/tools/make-standalone-toolchain.sh --platform=android-9 --install-dir=ndk-toolchain

ndk-toolchainが生成されていたらパスを設定

export NDK_ROOT="$NDK/ndk-toolchain" 
3 Go

適当なところでパッチ(goandroid)をクローン

git clone https://github.com/eliasnaur/goandroid.git

パスの設定

export GOPATH="$HOME/Develop/Golang"
export GOBIN="$GOPATH/bin"

ソースコードを持ってくる

hg clone https://code.google.com/p/go $GOPATH

パッチフォルダーをコピー

cp -a patches $GOPATH/.hg

Mercurialの設定

[extensions]
mq =
codereview = !

[ui]
username = Go<Go@mail.com>

パッチの適用

cd $GOPATH/src
hg qpush -a

ビルド

CGO_ENABLED=0 GOOS=linux GOARCH=arm ./make.bash  
CC="$NDK_ROOT/bin/arm-linux-androideabi-gcc" GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 $GOBIN/go install -tags android -a -v std  
cd ../..

動かす

goandroidには

  • hello-gl2 :: Javaアリ
  • nativeactivity :: Javaナシ

の2サンプルが入ってますが、手順はどちらも同じです

各フォルダ内のbuild.shを実行すると.soライブラリが生成されます
(build.sh内の../go/bin/$GOBINに置き換え)

project.propertiesを使用するバージョンに書き換え
(今日落としたならtarget=android-19)
Android端末を繋ぎ、下記のコマンドを実行するとインストールされます

ant -f android/build.xml clean debug install

書く

Javaから呼び出す関数の指定は

main.go
//export Java_net_goandroid_hellogl2_Engine_resize
func Java_net_goandroid_hellogl2_Engine_resize(env *C.JNIEnv, clazz C.jclass, width, height C.jint) {
        defer func() {
                if err := recover(); err != nil {
                        log.Fatalf("panic: resize: %v\n", err)
                }
        }()
        g.resize(int(width), int(height))
}

こんなかんじ。呼び出し元は

Engine.java
 static native void resize(int w, int h);

と、こんなかんじ。だいたい通常のJNIとcgoです

//export Java_(パッケージ)_(関数名)
func Java_(パッケージ)_(関数名)(env *C.JNIEnv, clazz C.jclass, ....) ... {
    return ...
}

変数名にC.jxxxxつけていくとだいたいうまくいきますʕ ◔ϖ◔ʔ

おわり

たのしいAndroidライフを!

30
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
29