赞
踩
使用Golang一处编写,横跨中Android & IOS 多端场景使用。golang提供gomobile跨平台开发库,我们可快速编译可直接Android & IOS 原生调用的SDK包,借助这一优势,可更加方便使用,白哪个比较Rust需要使用FFI转化调用更加方便。
本文主要介绍了Flutter 集成Golang,所以并不会在Flutter、Golang等开发环境搭建以及Dart、go语言上做介绍,本次使用VSCode作为编辑器。
考虑Android & IOS 同时演示效果,所以本文使用MacOS系统作为演示,如仅仅需做安卓上测试可跳过相关IOS的配置等操作。
从官网下载go安装包 https://golang.google.cn/dl/ 解压到本地,这里安装存放到 /usr/local/go 目录下
- GOPATH: go工作区, 即编写代码存放的目录
- GOROOT: go的安装目录
- 在
GOPATH
工作区目录下, 一般有3个目录, 分别是
- bin: 存储可执行bin文件
- pkg: 编译完成的文件
- src: 源代码文件
wget -c https://golang.google.cn/dl/go1.18.3.darwin-arm64.tar.gz sudo tar -xzvf go1.18.3.darwin-arm64.tar.gz -C /usr/local cd /usr/local/go code ~/.bash_profile # 增加如下几行 到 .bash_profile export GOROOT=/usr/local/go export PATH=$PATH:$GOROOT/bin export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin export GO111MODULE=on export GOPROXY=https://goproxy.cn # 添加 ~/.bash_profile 后保存 code ~/.zshrc source ~/.bash_profile # 执行让环境变量生效 source ~/.zshrc mkdir -p $GOPATH/src mkdir -p $GOPATH/bin mkdir -p $GOPATH/pkg
cd $GOPATH/src
mkdir demo
go mod init demo
创建 greeting.go 文件,并编写如下内容,中后面调用时候传入内容并返回传入内容结果,以便演示数据互相传递
gomobile init 初始化失败,请查看 完整流程 Flutter 集成 Rust 多语言跨端开发基础案例 中配置NDK相关内容配置好NDK之后,在执行 gomobile init
go get golang.org/x/mobile/cmd/gomobile
gomobile init
gomobile bind -target=android
gomobile bind -target=ios
构建后得到如图Android与IOS两个SDK文件
这里直接使用Android Studio创建插件,也可以使用vscode或命令方式创建插件
将golang项目构建出的Android与IOS平台SDK导入 Flutter 插件项目各种目录中
导入 Android 所需SDK 至 android/libs 目录下,首次需要创建libs目录。导入完成后目录图如下
导入 IOS 所需SDK 到 ios/Frameworks 目录下,首次需要创建Frameworks目录。导入完成后目录如下图所示
这里要注意的是 构建出 IOS SDK 目录Greeting.xcframework中有两个
我们导入 ios-arm64_x86_64-simulator 目录下的 Greeting.framework
打开android目录下build.gradle,添加引用SDK
project插件项目名称,file指定目录
打开 src/main/kotlin/com/example/demo/GomobileDemoPlugin.kt 文件,增加如下判断,调用golang sdk
修改 demo.podspec 添加引用SDK
打开 ios/Classes/SwiftGomobileDemoPlugin.swift 文件增加如下判断,调用golang sdk
由于这边Flutter 版本是3.0.2,生成插件分三个文件,旧版本是一个,为方便演示,不做目录结构修改,这里修改lib三个文件调用,由于难度较低,这里直接贴上修改后结果
gomobile_demo.dart
import 'gomobile_demo_platform_interface.dart';
class GomobileDemo {
Future<String?> getPlatformVersion() {
return GomobileDemoPlatform.instance.getPlatformVersion();
}
Future<String?> getSayHi(String text) {
return GomobileDemoPlatform.instance.getSayHi(text);
}
}
gomobile_demo_method_channel.dart
import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'gomobile_demo_platform_interface.dart'; /// An implementation of [GomobileDemoPlatform] that uses method channels. class MethodChannelGomobileDemo extends GomobileDemoPlatform { /// The method channel used to interact with the native platform. @visibleForTesting final methodChannel = const MethodChannel('gomobile_demo'); @override Future<String?> getPlatformVersion() async { final version = await methodChannel.invokeMethod<String>('getPlatformVersion'); return version; } @override Future<String?> getSayHi(String text) async { final sayHi = await methodChannel.invokeMethod<String>( 'getSayHi', {"text": text}, ); return sayHi; } }
gomobile_demo_platform_interface.dart
import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'gomobile_demo_method_channel.dart'; abstract class GomobileDemoPlatform extends PlatformInterface { /// Constructs a GomobileDemoPlatform. GomobileDemoPlatform() : super(token: _token); static final Object _token = Object(); static GomobileDemoPlatform _instance = MethodChannelGomobileDemo(); /// The default instance of [GomobileDemoPlatform] to use. /// /// Defaults to [MethodChannelGomobileDemo]. static GomobileDemoPlatform get instance => _instance; /// Platform-specific implementations should set this with their own /// platform-specific class that extends [GomobileDemoPlatform] when /// they register themselves. static set instance(GomobileDemoPlatform instance) { PlatformInterface.verifyToken(instance, _token); _instance = instance; } Future<String?> getPlatformVersion() { throw UnimplementedError('platformVersion() has not been implemented.'); } Future<String?> getSayHi(String text) { throw UnimplementedError('platformVersion() has not been implemented.'); } }D
打开example中main.dart 文件,将如下代码直接复制全部替换,这些都是基础内容,看不明白可以去flutter官网或者查阅相关基础教程
import 'package:flutter/material.dart'; import 'dart:async'; import 'package:flutter/services.dart'; import 'package:gomobile_demo/gomobile_demo.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { String _platformVersion = 'Unknown'; String _sayHi = 'Unknown'; final _gomobileDemoPlugin = GomobileDemo(); @override void initState() { super.initState(); initPlatformState(); initSayHiState(); } Future<void> initPlatformState() async { String platformVersion; try { platformVersion = await _gomobileDemoPlugin.getPlatformVersion() ?? 'Unknown platform version'; } on PlatformException { platformVersion = 'Failed to get platform version.'; } if (!mounted) return; setState(() { _platformVersion = platformVersion; }); } Future<void> initSayHiState() async { String sayHi; try { sayHi = await _gomobileDemoPlugin.getSayHi('你好') ?? 'Unknown platform version'; } on PlatformException { sayHi = 'Failed to get platform version.'; } if (!mounted) return; setState(() { _sayHi = sayHi; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Plugin example app'), ), body: Center( child: Column( children: [ Text('Running on: $_platformVersion\n'), Text('Hi: $_sayHi\n'), ], ), ), ), ); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。