woonizzooni

Golang으로 Android / iOS 앱 코드 작성하기 본문

Programming/Go

Golang으로 Android / iOS 앱 코드 작성하기

woonizzooni 2020. 11. 6. 22:45

Windows10 환경에서의 내용을 작성했으나, MacOS등 다른 환경에서도 큰 차이 없을 것으로 보임.

iOS의 경우는 실습에서는 제외.

 

나온지는 꽤 된 것 같은데 안해봤으니 한번 보고 넘어간다는 차원에서....


TL; DR

 

[샘플코드 및 예제]

github.com/woonizzooni/go-mobile-example

github.com/woonizzooni/go-android-example

 

$ gomobile build -target=android github.com/woonizzooni/go-mobile-example/cmd/basic

  --> basic.apk파일 생성

 

$ gomobile build -target=android github.com/woonizzooni/go-mobile-example/cmd/flappy

  --> flappy.apk파일 생성

 

$ gomobile bind -target=android -o message.aar github.com/woonizzooni/go-mobile-example/pkg/message

  --> message.aar파일 생성

Android Studio에서 go-android-example 앱 빌드 & 설치

 

[소감]

[1] golang으로 작성한 암호화 모듈, 그래픽스 처리 모듈을 1개의 프로젝트로 관리하면서

Android/iOS 향 모듈 바인딩 되니 편리한 점이 확실히 있기는 함.

[2] android jni코드 작성하려면, mk파일 작성해야 하고, jni코드 작성해야 하고, 패키지명과 잘 맞춰야 하고, shared/static 맞춰서 빌드시켜하고, 이래저래 (?) 손 많이 타는데 이건 그에 비해 한게 전혀 없음.

 

 

[참고]

github.com/golang/go/wiki/Mobile

github.com/golang/mobile

...

Current limitations are listed below.

  • Only a subset of Go types are currently supported.
  • Language bindings have a performance overhead.
  • There are a few limitations on how the exported APIs should look due to the limitations of the target language.

...

 

> mobile : app, cmd/gomobile, cmd/gobind, exampe, ..

pkg.go.dev/golang.org/x/mobile

godoc.org/golang.org/x/mobile


o 사전 준비

 - Android Studio 및 SDK 설치 developer.android.com/studio

 - Go 실행파일(SDK? 대충 개발 환경이라고 치자) 설치 golang.org/dl 

 - Android 단말 PC에 USB연결 (adb 장치 식별된 상태)

 

o Go 환경 구성

  - 별도로 GOPATH를 설정하지 않아 대충 다음과 같고, 나머지 변수들은 특별히 다루지 않음.

    GOROOT=c:\go

    GOPATH=c:\Users\내이름\go

    --> 두 경로의 bin폴더를 PATH에 등록 (${GOROOT}/bin 혹은 %GOROOT%\bin 대충 이렇게...)

 

  - go코드를 Android/iOS 용으로 빌드 하기 위해 gomobile실행파일 다운로드

    명령프롬프트 실행 (터미널 실행)

    --> GOBIN을 설정하지 않은 상태면 GOPATH/bin에 gomobile(.exe)이 다운되어 있음을 확인

    > go get golang.org/x/mobile/cmd/gomobile

  - 라이브러리 빌드/바인딩을 위해 go bind 설치

    > go get golang.org/x/mobile/cmd/gobind

 

여기까지 진행했을 때, go(.exe), gombile(.exe), gobind(.exe) 3개의 실행파일이 있어야 함.

각각 다음과 같은 옵션 지원.

> gomobile --help
Gomobile is a tool for building and running mobile apps written in Go.

To install:

        $ go get golang.org/x/mobile/cmd/gomobile
        $ gomobile init

At least Go 1.10 is required.
For detailed instructions, see https://golang.org/wiki/Mobile.

Usage:

        gomobile command [arguments]

Commands:

        bind        build a library for Android and iOS
        build       compile android APK and iOS app
        clean       remove object files and cached gomobile files
        init        build OpenAL for Android
        install     compile android APK and install on device
        version     print version

Use 'gomobile help [command]' for more information about that command.

> gomobile bind --help
usage: gomobile bind [-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]

Bind generates language bindings for the package named by the import
path, and compiles a library for the named target system.

The -target flag takes a target system name, either android (the
default) or ios.

For -target android, the bind command produces an AAR (Android ARchive)
file that archives the precompiled Java API stub classes, the compiled
shared libraries, and all asset files in the /assets subdirectory under
the package directory. The output is named '<package_name>.aar' by
default. This AAR file is commonly used for binary distribution of an
Android library project and most Android IDEs support AAR import. For
example, in Android Studio (1.2+), an AAR file can be imported using
the module import wizard (File > New > New Module > Import .JAR or
.AAR package), and setting it as a new dependency
(File > Project Structure > Dependencies).  This requires 'javac'
(version 1.7+) and Android SDK (API level 15 or newer) to build the
library for Android. The environment variable ANDROID_HOME must be set
to the path to Android SDK. Use the -javapkg flag to specify the Java
package prefix for the generated classes.

By default, -target=android builds shared libraries for all supported
instruction sets (arm, arm64, 386, amd64). A subset of instruction sets
can be selected by specifying target type with the architecture name. E.g.,
-target=android/arm,android/386.

For -target ios, gomobile must be run on an OS X machine with Xcode
installed. The generated Objective-C types can be prefixed with the -prefix
flag.

For -target android, the -bootclasspath and -classpath flags are used to
control the bootstrap classpath and the classpath for Go wrappers to Java
classes.

The -v flag provides verbose output, including the list of packages built.

The build flags -a, -n, -x, -gcflags, -ldflags, -tags, -trimpath, and -work
are shared with the build command. For documentation, see 'go help build'.
> gobind --help
Usage of gobind:
  -bootclasspath string
        Java bootstrap classpath.
  -classpath string
        Java classpath.
  -javapkg string
        custom Java package path prefix. Valid only with -lang=java.
  -lang string
        target languages for bindings, either java, go, or objc. If empty, all languages are generated.
  -outdir string
        result will be written to the directory instead of stdout.
  -prefix string
        custom Objective-C name prefix. Valid only with -lang=objc.
  -tags string
        build tags.

 

 

o 공개된 예제 중 2개만 경험(?) 해보고, 1개는 따라해보자.

    github.com/golang/mobile/tree/master/example

    1) basic : opengl  / 쉐이더 코드

      $ gomobile install golang.org/x/mobile/example/basic

      --> 실행 위치에 basic.apk파일이 생성되어 있고, 기기에는 basic 앱이 설치됨.

      실행모습은 아래 그림과 같음.

 

    2) flappy : 고퍼 캐릭터 점프(?) 게임

      $ gomobile install golang.org/x/mobile/example/flappy

      --> 마찬가지로 flappy.apk파일이 생성되어 있고, flappy앱이 설치되어 있음.

      실행하면 아래 그림과 같고 터치하면 고퍼(?) 캐릭터가 점프...

 

    3) bind : 이걸 보고 라이브러리 샘플로 따라 해보자.

 

 

o Android 프로젝트 생성

1. Android Studio 실행

2. Create New Project

3. Basic Activity 선택 & Next

4. 앱 명세 작성

  - Name : Gopher

  - Package Name : com.github.woonizzooni

  - Save location : 적당한 곳에 .. (난 D:\Workspace\golang-android-example)

  - Language : 마음에 드는 걸로... 난 Kotlin

  - 나머지는 기본 값 그대로..

  Finish 클릭

 

o Go 모듈 프로젝트 생성

1. 명령프롬프트 터미널 실행 & 내 워크스페이스로 이동

2. 모듈 프로젝트 생성

  $ mkdir golang-mobile-example

  $ go mod init github.com/woonizzooni/go-mobile-example

    go: creating new go.mod: module github.com/woonizzooni/go-mobile-example

 

3. 위 예시도 이왕이면 가져올까 싶어서 dependencies 모듈 다운로드

  $ go get go golang.org/x/mobile

    go: golang.org/x/mobile upgrade => v0.0.0-20200801112145-973feb4309de

 

4. 프로젝트 레이아웃 구성

  go-mobile-example/

      cmd/

          basic/   : github.com/golang/mobile/tree/master/example/basic

          flappy/ : github.com/golang/mobile/tree/master/example/flappy

      pkg/

          message/message.go

package message

import "fmt"

// Greetings ...
func Greetings(name string) string {
	return fmt.Sprintf("Hey, %s!", name)
}

// Goodbyes ...
func Goodbyes(name string) string {
	return fmt.Sprintf("Bye, %s!", name)
}

5. 라이브러리 빌드

  $ gomobile bind -o message.aar .\pkg\message

     --> message-sources.jar, message.aar 2개 파일 생성됨. -target=android를 하지 않아도 aar때문에 된건가...

     --> ios용이라면 -target=ios를...

 

6. (선택) apk 설치 파일 생성

  $ gomobile build -target=android .\cmd\basic --> basic.apk 파일 생성됨.

  $ gomobile build -target=android .\cmd\flappy --> flappy.apk 파일 생성됨.

  --> target=ios 로 하면 ios용...

 

 

o Android <-> Go모듈 연동

  1. /Workspace/go/go-mobile-example/message.aar 파일을

     /Workspace/go/go-android-example/app/libs 폴더에 복사해넣고 Android Studio화면으로...

  2. go-android-example/app/build.gradle 열고 dependencies에 아래 한줄 추가

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.aar'])
    ......

  3. go-android-example/app/src/main/java/com/github/woonizzooni/MainActivity.kt 파일열고 아래와 같이 변경

      이때 Message 찾는 과정에서 ./app/libs/message.aar를 선택해야 함.

package com.github.woonizzooni

import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import message.Message

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(findViewById(R.id.toolbar))

        findViewById<FloatingActionButton>(R.id.fab).setOnClickListener { view ->
            //Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
            //        .setAction("Action", null).show()

            Snackbar.make(view, this.message(), Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        return when (item.itemId) {
            R.id.action_settings -> true
            else -> super.onOptionsItemSelected(item)
        }
    }

    private var clickNum=0
    private fun message(): String {
        clickNum += 1
        if (clickNum % 2 == 1) {
            return Message.greetings("$clickNum")
        }
        return Message.goodbyes("$clickNum")
    }
}

  4. 앱 설치 & 실행

  - 편지함 클릭하면 go코드로 작성한 greetings()와 goodbyes()함수로부터 반환된 문자열이 출력됨.

'Programming > Go' 카테고리의 다른 글

golang - redigo 사용시 ping  (0) 2020.08.03
Comments