Flutter原生功能绑定插件bindgo的使用

Flutter原生功能绑定插件bindgo的使用

BindGo

BindGo Logo
Platforms Supported Modes Supported

使用Dart调用Shell,完成将Golang CGO代码编译为so、dll、a、WASM等格式,并将其放置在每个Flutter平台对应的源文件目录中。


入门指南

首先,在你的pubspec.yaml文件中添加bindgo作为开发依赖。因为它是一个命令行工具,所以应该放在dev_dependencies中。

dev_dependencies:
  bindgo: any

使用方法

步骤1: 在pubspec.yaml文件中添加配置

例如:

bindgo:
  name: test # 动态库输出名称
  main: ./test # Golang代码主包所在的目录
  platforms:
    windows:
      arch:
        - 'amd64'
    android:
      arch:
        - 'arm64'
      cc: '${NDK}/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android27-clang.cmd'

步骤2: 在终端中运行以下命令

dart run bindgo

或者

flutter pub run bindgo:run

额外信息

查看当前版本的golang支持的操作系统和架构:

go tool dist list

例如:

# golang v1.17.2

...
android/386
android/amd64
android/arm
android/arm64
---
darwin/amd64
darwin/arm64
...
ios/amd64
ios/arm64
---
js/wasm
---
linux/386
linux/amd64
linux/arm
linux/arm64
...
windows/386
windows/amd64
windows/arm
windows/arm64

完整示例Demo

为了帮助你更好地理解如何使用bindgo插件,这里提供一个完整的示例Demo。

1. 创建一个新的Flutter项目

flutter create bindgo_example
cd bindgo_example

2. 在pubspec.yaml文件中添加bindgo依赖

dev_dependencies:
  bindgo: any

3. 添加bindgo配置

pubspec.yaml文件中添加以下配置:

bindgo:
  name: test # 动态库输出名称
  main: ./test # Golang代码主包所在的目录
  platforms:
    windows:
      arch:
        - 'amd64'
    android:
      arch:
        - 'arm64'
      cc: '${NDK}/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android27-clang.cmd'

4. 创建一个简单的Golang代码

./test目录下创建一个名为main.go的文件,并添加以下代码:

// main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello from Go!")
}

5. 运行bindgo命令

在终端中运行以下命令来编译Golang代码并生成动态库:

dart run bindgo

或者

flutter pub run bindgo:run

6. 在Flutter中调用Golang代码

在Flutter项目中创建一个Dart文件(如main.dart),并添加以下代码:

import 'dart:ffi';
import 'package:path/path.dart' as p;
import 'package:flutter/services.dart' show rootBundle;

void main() {
  // 加载动态库
  final dylib = Platform.isAndroid ? 
    DynamicLibrary.open(p.join('lib', 'test.so')) :
    DynamicLibrary.process();

  // 调用Golang函数
  final printMessage = dylib.lookupFunction<
      Void Function(), 
      void Function()
    >('PrintMessage');

  printMessage();
}

7. 运行Flutter应用

最后,运行你的Flutter应用来验证一切是否正常工作:

flutter run

更多关于Flutter原生功能绑定插件bindgo的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter原生功能绑定插件bindgo的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,使用原生功能绑定插件(如bindgo或类似的插件)通常涉及与平台特定的代码(iOS的Swift/Objective-C和Android的Kotlin/Java)进行交互。尽管bindgo不是官方Flutter插件,但假设它是一个第三方插件,用于简化原生功能绑定,以下是如何在Flutter项目中集成和使用它的一个示例框架。

请注意,由于bindgo的具体实现和API可能有所不同,以下代码将基于一个假设的bindgo插件的功能和结构。实际使用时,请查阅bindgo的官方文档以获取准确的API和用法。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加bindgo依赖(假设它存在于pub.dev上或你的私有包仓库中):

dependencies:
  flutter:
    sdk: flutter
  bindgo: ^x.y.z  # 替换为实际的版本号

然后运行flutter pub get来获取依赖。

2. 配置原生代码(如果需要)

某些插件可能需要额外的原生代码配置。对于iOS,这通常涉及在ios/Runner/目录下的文件(如Info.plistAppDelegate.swift/m)中进行修改。对于Android,可能需要在android/app/src/main/目录下的文件(如AndroidManifest.xmlMainActivity.kt/java)中进行配置。

由于bindgo的具体要求未知,这里不提供具体的配置代码。请查阅bindgo的文档了解是否需要这些配置。

3. 使用bindgo插件

假设bindgo提供了一个方法来获取设备信息,以下是如何在Flutter中调用这个方法的示例代码:

Dart代码(Flutter层)

import 'package:flutter/material.dart';
import 'package:bindgo/bindgo.dart';  // 假设bindgo的导入路径是这样的

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String deviceInfo = 'Loading...';

  @override
  void initState() {
    super.initState();
    _getDeviceInfo();
  }

  Future<void> _getDeviceInfo() async {
    try {
      // 假设bindgo提供了一个名为getDeviceInfo的方法
      var info = await Bindgo.deviceInfo();
      setState(() {
        deviceInfo = info;
      });
    } catch (e) {
      setState(() {
        deviceInfo = 'Error: ${e.message}';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Bindgo Example'),
        ),
        body: Center(
          child: Text(deviceInfo),
        ),
      ),
    );
  }
}

原生代码(假设需要)

如果bindgo需要在原生层执行特定操作,它通常会在iOS和Android项目中包含相应的原生代码。以下是一个假设的原生代码结构,用于说明如何可能需要在原生层实现功能。

iOS (Swift)
// iOS/Runner/BindgoPlugin.swift
import Flutter

public class BindgoPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterRegistrar) {
    let channel = FlutterMethodChannel(name: "com.example.bindgo", binaryMessenger: registrar.messenger())
    let instance = BindgoPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "deviceInfo":
      let deviceInfo = UIDevice.current.systemName + " " + UIDevice.current.systemVersion
      result(deviceInfo)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}
Android (Kotlin)
// android/app/src/main/kotlin/com/example/bindgo/BindgoPlugin.kt
package com.example.bindgo

import android.content.Context
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result

class BindgoPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
  private lateinit var context: Context
  private lateinit var channel: MethodChannel

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPluginBinding) {
    context = flutterPluginBinding.applicationContext
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.example.bindgo")
    channel.setMethodCallHandler(this)
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "deviceInfo") {
      val deviceInfo = android.os.Build.FINGERPRINT
      result.success(deviceInfo)
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    // No-op for now
  }

  override fun onDetachedFromActivityForConfigChanges() {
    // No-op for now
  }

  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
    // No-op for now
  }

  override fun onDetachedFromActivity() {
    // No-op for now
  }
}

请注意,上述原生代码是假设性的,并且bindgo插件的实际实现可能会有所不同。务必查阅bindgo的官方文档和源代码以获取准确的实现细节。

结论

上述代码提供了一个如何在Flutter项目中集成和使用假设的bindgo插件的框架。实际使用时,请根据bindgo的官方文档进行调整和修改。

回到顶部