最近有個項目架構是 react native寫應用介面,go寫底層,大體思路:react native 可以通過NativeModules 調用原生代碼,go代碼可以通過gomobile架構編譯成Android的.arr檔案和iOS的.framework檔案,通過添加依賴檔案到本地即可實現js->java/oc->go的調用.
現將從安裝環境->運行成功過程記錄在此:
整個過程:
1,搭建go環境;
2,clone gomobile 架構,書寫go代碼,通過gomobile編譯成.arr&&.framework;
3,搭建react native環境,初始化一個react native項目;
4,在react native app中通過Android Studio中添加.arr依賴,在Xcode中添加.framework依賴;
5,寫Android&&iOS 通過NativeModules調用本地原生代碼;
第1步,搭建go語言環境
下載安裝請參考:
Go語言開發環境搭建詳解
這裡有個坑,Mac下直接下載安裝pkg之後,需要手動去.bash_profile裡面添加GOROOT和GOPATH,否則gomobile build時提示找不到ndk,詳細請參考:
go環境變數配置
第2步,搭建gomobile環境
具體步驟請參考:
https://github.com/golang/go/wiki/Mobile
需要注意的是:
1,go get golang.org/x/mobile/cmd/gomobile命令被牆,可以自己把gomobile項目clone到$GOPATH/src/golang.org/x下面,然後執行gomobile init
這裡編譯 gomobile 下example目錄下的hello.go檔案
go代碼很簡單:
package helloimport "fmt"func Greetings(name string) string { return fmt.Sprintf("Welcome To Tradove.\nHello, %s!", name)}
然後編譯Android .arr檔案:
gomobile bind -target=android golang.org/x/mobile/example/bind/hello
產生iOS用的.framework檔案
gomobile bind -target=ios golang.org/x/mobile/example/bind/hello
備忘:
Mac 下.arr和.framework檔案會被放在使用者根目錄下面
第3步:搭建react native 環境:
這裡不多說,請參考官網:
https://facebook.github.io/react-native/docs/0.55/getting-started.html
初始化一個react native 項目
頁面很簡單,就一個按鈕
type Props = {};export default class App extends Component<Props> { render() { return ( <View style={styles.container}> <TouchableOpacity onPress={() => { this._getFromNative(); }} style={styles.touchView}><Text style={styles.touchText}>{' get values from native '}</Text></TouchableOpacity> </View> ); } _getFromNative() { const rnParam = Platform.select({ ios: 'str from ios', android: 'str from android' }); GoMobileModules.getNativeGo(rnParam, (str) => { alert(str); }); }}
第4步,將.arr和.framework檔案依賴進react native項目中
Android部分:
使用android studio 開啟react native 工程目錄/android(注意彈出提示更新時不要更新)
選擇
File->new module->import .jar/.arr package
001.png
之後在app/build.gradle檔案dependencies裡添加以下一行
compile project(':hello')
詳細可參考:
Android studio2.3匯入aar包
iOS部分:
使用Xcode 開啟react native 工程目錄/ios
- 下載好所需要的第三方提供的.framework
2)將第三方.framework檔案拷貝到工程所處的檔案夾中
001.png
(將檔案拷入)
- 選中項目名稱
4)選中TARGETS
5)選中Build Phases
6)在Link Binary With Libraries中添加
002.png
第5步,書寫react native 調用Android&&iOS調用原生的代碼
詳細內容請參考:
這裡
Android 部分:
GoMobileBridge.class
public class GoMobileBridge implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new GoMobileModule(reactContext)); return modules; } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); }}
GoMobileModule.class
public class GoMobileModule extends ReactContextBaseJavaModule { public GoMobileModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return this.getClass().getSimpleName(); } @Nullable @Override public Map<String, Object> getConstants() { return super.getConstants(); } @ReactMethod public void getNativeGo(String rnStr, Callback callback) { String greetings = hello.Hello.greetings(rnStr); callback.invoke(greetings); }}
iOS原生代碼:
GoMobileModule.h
#ifndef GoMobileModule_h#define GoMobileModule_h#import <Foundation/Foundation.h>#import <React/RCTBridgeModule.h>@interface GoMobileModule : NSObject<RCTBridgeModule>@end#endif /* GoMobileModule_h */
GoMobileModule.m
#import "GoMobileModule.h"#import <React/RCTLog.h>#import "Hello/Hello.h"@implementation GoMobileModuleRCT_EXPORT_MODULE();//從go層擷取資料RCT_EXPORT_METHOD(getNativeGo:(NSString *) rnStr :(RCTResponseSenderBlock)callback{ NSString *goStr=HelloGreetings(rnStr); callback(@[goStr]);});@end
運行結果:
001.png
002.png