雖然 Go 並不是一門新語言,不過最近兩年來 Go 還是增加了很多有趣的特性,而且使用這門語言的知名項目的數量也在快速的增長。我寫過一篇文章,介紹了 SitePoint 用到的編程語言,其中提到了移動端的支持,所以我覺得需要研究一下可能性。
我很高興 Android 是支持 Go 語言的,這一方面應該是二者都是 Google 的技術,另一方面恐怕也與開發者希望用 Go 替換 Java 的願望有關。
你需要安裝 Golang 1.5+。
接下來需要安裝 GoMobile 工具,用於編譯和運行 Android 和 iOS 的應用:
go get golang.org/x/mobile/cmd/gomobile
gomobile init
我們會參考 gomobile 包裡的例子,位於 GoLangInstalldir/src/golang.org/x/mobile/example/。如果你沒有安裝這些例子,參考下面的命令來安裝:
go get -d golang.org/x/mobile/example/basic
對於很多應用,編譯 Go 的 Native 應用時,忽略那些平台相關的庫和接口是可以接受的。如果是這樣的情況,編譯已有的 Go 代碼是很輕松的,我們可以選擇使用一個功能子集,這些功能包括:
我們將從已有的 gomobile 項目裡的一些例子開始,你可以用自己項目裡的文件替換它們。
gomobile build -target=android golang.org/x/mobile/example/basic
部署到設備上
gomobile install golang.org/x/mobile/example/basic
gomobile build -target=ios golang.org/x/mobile/example/basic
跟 Android 不一樣,對於 iOS 來說沒有一個統一的部署命令,你需要用你熟知的方式把包拷貝到設備或者模擬器上,例如使用 ios-deploy 工具。
可以用上面的步驟,試試 golang.org/x/mobile/example/audio 這個例子。
讓我們深入了解一下 audio 這個例子(詳細的代碼就不列出了了),你並不需要對 Go 語言非常精通(我就是不太精通),我們先了解一下都能干些啥。
首先你可以看到一些 import 語句:
import (...
"golang.org/x/mobile/app"
"golang.org/x/mobile/asset"...)
如果你查看一下 import 的這些包所在的目錄 GoLangInstalldir/src/golang.org/x/mobile/* 下的文件,你可以發現那些編譯到你的代碼裡的那些 Java 和 Objective-C 文件。
再進一步了解一下,你可以在代碼裡找到對這些 import 的包(例如 app 和 glctx)的引用。
Going Native
我們可以用 Go 寫代碼,然後構建一個緊湊的優化過的 native 應用,但是目前這個應用還不是完全的 native 的風格,因為所有依賴的庫還都是 Java 或者 Objective-C / Swift 的。我們怎樣來改善這個體驗呢?
Go Mobile 團隊給我們了另一個選擇,可以在一個 native 應用裡使用 go 的包(也即你的程序)。特別是共享一些公共的 Go 代碼,把它們綁定到 native 的代碼上是非常好用的。這種方式上手很快,不過長期來說維護會比較麻煩一些。
如果使用 Android Studio,可以導入項目 GoLangInstalldir/src/golang.org/x/mobile/example/bind/android,打開 build.grade (hello 模塊)文件,更新一下 GOPATH 和 GO 的路徑,下面是我的文件內容(我是用 Homebrew 安裝的 GoLang):
同步 Gradle 後,應用就可以部署到仿真器或者真實設備上了。
注意: 當前這種方式只支持基於 ARM 的設備和仿真器。
讓我們看一下 Java 和 Go 的代碼:
MainActivity.java
package org.golang.example.bind;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import go.hello.Hello;
public class MainActivity extends Activity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.mytextview);
// Call Go function.
String greetings = Hello.Greetings("Android and Gopher");
mTextView.setText(greetings);
}}
src/golang.org/x/mobile/example/bind/hello/hello.go
package hello
import "fmt"
func Greetings(name string) string {
return fmt.Sprintf("Hello, %s!", name)}
通過 import go.hello.Hello 來 import 對應的 go 文件,文件裡的 Greetings 函數在 Java 代碼裡可以通過 Hello.Greetings 來調用。並不需要太復雜的步驟,在go 函數和 native 的 UI 元素之間就可以建立上綁定關系。
把一個 iOS 應用和 Go 程序直接進行綁定需要不同的步驟。首先需要運行下面的命令:
cd GoLang_Install_dir/src/golang.org/x/mobile/example/bind
gomobile bind -target=ios golang.org/x/mobile/example/bind/hello
這樣會在當前目錄下創建一個叫 Hello.framework 的 bundle,在項目裡可以使用它。
在 Xcode 打開例子中的 iOS 項目,位於 GoLangInstalldir/src/golang.org/x/mobile/example/bind/ios/bind.xcodeproj ,把 Hello.framework 拖到項目裡,如果需要,選擇"Copy items"。目錄結構現在看上去是下面這樣:
構建和運行這個應用(更像 Android 應用),我們可以看到在 Objective-C 代碼裡進行 Go 函數的調用。
看一下現在的代碼:
#import "ViewController.h"
#import "hello/Hello.h" // Gomobile bind generated header file in hello.framework
@interface ViewController ()
@end
@implementation ViewController
@synthesize textLabel;
- (void)loadView {
[super loadView];
textLabel.text = GoHelloGreetings(@"iOS and Gopher");
}
@end
#import "hello/Hello.h"導入了之前生成的 framework,textLabel.text = GoHelloGreetings(@"iOS and Gopher");調用了它暴露出的一個函數來設置一個 label 的值。
也可以使用同樣是自動生成的基於 Swift 的項目裡的 Objective-C 的 framework,像下面這樣:
let msg = Hello.GoHelloGreetings("gopher")
是否值得?
嗯,簡單的說可能是不值得。如果你已經在使用 Go 來寫應用了,並且不在乎應用是否 native 的,那麼你可以放開手繼續做,因為你已經知道了構建和部署用 Go 寫的 native 應用是很簡單的。如果你打算花更多的精力嘗試一下綁定,你可以走的更遠一些,不過還是需要稍微控制一下。
如果你沒在用 Go,那麼就不太值的現在就在開發 native 的移動應用時考慮 Go。不過我有很強烈的預感,在不久的將來,Go 會成為這方面很有潛力的選擇的。最後歡迎你的建議和意見。
如何為Linux安裝Go語言 http://www.linuxidc.com/Linux/2015-09/123114.htm
Linux系統入門學習-在Linux中安裝Go語言 http://www.linuxidc.com/Linux/2015-02/113159.htm
Ubuntu 安裝Go語言包 http://www.linuxidc.com/Linux/2013-05/85171.htm
《Go語言編程》高清完整版電子書 http://www.linuxidc.com/Linux/2013-05/84709.htm
Go語言並行之美 -- 超越 “Hello World” http://www.linuxidc.com/Linux/2013-05/83697.htm
我為什麼喜歡Go語言 http://www.linuxidc.com/Linux/2013-05/84060.htm
Go語言內存分配器的實現 http://www.linuxidc.com/Linux/2014-01/94766.htm
英文原文:iOS and Android Programming with Go