Flutter 调用Golang

· 16 mins read

gomobile: 负责移动端 cgo: 打包动态库负责桌面端

gomobile

安卓

1. 编译 aar

main.go

package libHello

func SayHello() string {
	return "hello"
}

编译 aar

gomobile bind --target android

2. 放置 arr 文件和修改 build.gradle

将打包出来的aar文件放到 Flutter 项目下的android-> app->libs目录下

如果libs不存在就创建

编辑 build.gradle 文件 位置 android -> app -> build.gradle

repositories {
        flatDir {
            dirs 'libs'
        }
    }

libHello 是打包出来的文件名(文件名和 go package 名一样)

dependencies {
    implementation(name: 'libHello 修改一下', ext: 'aar')
}

3. 修改 MainActivity.java(或者 MainActivity.kt)

参考文章 MainActivity.kt

package com.example

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

<!-- 导入arr包  -->
import libHello.LibHello

class MainActivity: FlutterActivity() {
    <!-- 设置CHANNEL -->
    private val CHANNEL = "demo.libHello"
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
                call, result -> when(call.method) {
                    "sayHello" -> {
                        var title = LibHello.sayHello()
                        result.success(title)
                    }
                    else -> {
                        result.notImplemented()
                    }
                }

        }
    }
}

4. Flutter 调用

MethodChannel() 是上一步的 CHANNEL 名 channel.invokeMethod() 调用方法

const channel = MethodChannel('demo.libHello');
    final hi = await channel.invokeMethod('sayHello');
    print(hi.toString());

ios

1. 编译

gomobile bind --target ios

2. 放置文件和引入

将编译出来的 libHello.xcframework下的->ios-arm64->LibHello.framework 文件 放到ios->Frameworks下 (没有 Frameworks 文件夹就创建) 如果只放ios-arm64->LibHello.framework不能使用就将打包出来的libHello.xcframework全放进去

参考文章 使用Xcode打开项目ios目录下的Runner.xcworkspace将刚刚放到Frameworks下,按图引入LibHello.framework Embed 设置成 Do Not Embed 2023-11-19_00-03-56

3. 修改 AppDelegate.swift

位置 ios->Runner->AppDelegate.swift

import Flutter
import UIKit
import LibHello

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
    let batteryChannel = FlutterMethodChannel(
      name: "demo.libHello",
      binaryMessenger: controller.binaryMessenger)
    batteryChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
      switch call.method {
      case "sayHello":
        if let title = LibHelloSayHello() as? String {
          result(title)
        } else {
          result(FlutterError(code: "UNAVAILABLE", message: "Unable to retrieve hello message", details: nil))
        }

      default:
        result(FlutterMethodNotImplemented)
      }
    })
    GeneratedPluginRegistrant.register(with: self)

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

4. Flutter 调用

MethodChannel() 是上一步的 CHANNEL 名 channel.invokeMethod() 调用方法

const channel = MethodChannel('demo.libHello');
    final hi = await channel.invokeMethod('sayHello');
    print(hi.toString());

参考

NDK 错误 安卓参考 github 项目参考 ios 参考