Flutter原生工具链Rust镜像插件native_toolchain_rust_mirror的使用
Flutter原生工具链Rust镜像插件native_toolchain_rust_mirror的使用
库用于与rustup
和cargo
交互,当构建用Rust编写的Dart和Flutter原生资产时。
原生资产目前是一个实验性功能,仅在Flutter主分支上可用,并且需要通过flutter config
启用:
flutter config --enable-native-assets
使用方法
要将Rust代码与Flutter或Dart包一起构建,需要执行以下步骤:
- 将
native_toolchain_rust
和native_assets_cli
添加为项目的依赖项:
dart pub add native_toolchain_rust
dart pub add native_assets_cli
- 在项目根目录下创建一个构建脚本
hook/build.dart
:
import 'dart:io';
import 'package:native_toolchain_rust/native_toolchain_rust.dart';
import 'package:native_assets_cli/native_assets_cli.dart';
void main(List<String> args) async {
try {
await build(args, (BuildConfig buildConfig, BuildOutput output) async {
final builder = RustBuilder(
// 原生资产ID由包名和crate名组成。
package: '<你的包名>',
cratePath: 'rust',
buildConfig: buildConfig,
);
await builder.run(output: output);
});
} catch (e) {
// ignore: avoid_print
print(e);
exit(1);
}
}
此假设您的Rust代码位于包根目录下的rust
目录中。该crate必须是cdylib
。
- 在您的包根目录中添加
native_manifest.yaml
文件。这一步不是严格必需的,但它会让native_doctor
知道您的包所需的工具链要求:
version: 0.1.0
requirements:
ndk:
version: 25.1.8937393
rust:
stable:
version: 1.77.2
要在代码中引用原生资产库,您可以使用@ffi.DefaultAsset
注解:
@ffi.DefaultAsset('package:<flutter包名>/<rust_crate_name>')
library rust;
import 'dart:ffi' as ffi;
@ffi.Native<ffi.IntPtr Function(ffi.IntPtr, ffi.IntPtr)>()
external int sum(
int a,
int b,
);
完整的示例可以在这里查看。
使用包含Rust原生资产的包
包含Rust代码的包依赖于开发机器上安装的Rust工具链。为了使这一过程尽可能无摩擦,native_toolchain_rust
会检测Rust工具链是否已安装且是最新的。如果没有,则建议运行native_doctor
工具以自动安装和配置必要的工具链。
例如,当用户尝试在没有安装Rust的情况下构建包时,会显示以下错误消息:
Rustup not found.
Please run native_doctor in your project to fix the issue:
dart pub global activate native_doctor
dart pub global run native_doctor
以下是native_doctor
在一个没有Rust安装且NDK过时的计算机上的输出:
Project: example (Flutter)
Buildable platforms: macos, ios, android
Native toolchain: NDK
[✗] NDK installed, but too old
! Installed versions: 23.1.7779620
! Required minimum version: 25.1.8937393
Native toolchain: Rust
[✗] Rustup not found
[✗] Toolchain stable not installed
! Required minimum version: 1.77.2
! Missing targets: arm-linux-androideabi, aarch64-linux-android, i686-linux-android,
x86_64-linux-android, aarch64-apple-ios, x86_64-apple-ios, aarch64-apple-ios-sim, aarch64-apple-darwin,
x86_64-apple-darwin
Proposed actions:
• (NDK) Install NDK 25.1.8937393 or newer
• (Rust) Install rustup
• (Rust) Install toolchain stable
• (Rust) Install targets arm-linux-androideabi, aarch64-linux-android, i686-linux-android,
x86_64-linux-android, aarch64-apple-ios, x86_64-apple-ios, aarch64-apple-ios-sim, aarch64-apple-darwin,
x86_64-apple-darwin for toolchain stable
Do you want native doctor to perform proposed actions? (y/N)
确认后,native_doctor
会自动安装正确的NDK版本、所需的Rust工具链和目标:
• Fetching NDK list... [done]
• Installing NDK 26.3.11579264 [done]
• Installing rustup [done]
• Installing Rust toolchain stable [done]
• Installing target arm-linux-androideabi for toolchain stable [done]
• Installing target aarch64-linux-android for toolchain stable [done]
• Installing target i686-linux-android for toolchain stable [done]
• Installing target x86_64-linux-android for toolchain stable [done]
• Installing target aarch64-apple-ios for toolchain stable [done]
• Installing target x86_64-apple-ios for toolchain stable [done]
• Installing target aarch64-apple-ios-sim for toolchain stable [done]
• Installing target aarch64-apple-darwin for toolchain stable [done]
• Installing target x86_64-apple-darwin for toolchain stable [done]
更多关于Flutter原生工具链Rust镜像插件native_toolchain_rust_mirror的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter原生工具链Rust镜像插件native_toolchain_rust_mirror的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中集成和使用native_toolchain_rust_mirror
插件的示例代码和步骤。这个插件假设是用于在Flutter应用中集成Rust代码的原生工具链镜像。需要注意的是,具体的插件实现细节可能有所不同,因此以下示例是一个概念性的展示,实际使用时需要参考插件的官方文档。
步骤一:添加依赖
首先,在你的pubspec.yaml
文件中添加native_toolchain_rust_mirror
依赖:
dependencies:
flutter:
sdk: flutter
native_toolchain_rust_mirror:
git:
url: <插件的Git仓库URL>
ref: <分支或标签>
确保将<插件的Git仓库URL>
和<分支或标签>
替换为实际的仓库地址和版本。
步骤二:配置原生代码
由于native_toolchain_rust_mirror
插件涉及到原生代码(Rust),你需要在Flutter项目的原生部分(iOS和Android)进行配置。
iOS配置
-
打开
ios/
目录下的Podfile
,确保platform
设置支持你的Rust代码所需的最低iOS版本。 -
在
ios/
目录下运行pod install
来更新Pod配置。
Android配置
-
编辑
android/app/build.gradle
文件,确保minSdkVersion
和targetSdkVersion
适合你的Rust代码需求。 -
在
android/settings.gradle
文件中,确保包含了必要的原生模块配置(如果有的话)。
步骤三:编写Rust代码
创建一个Rust库,并将其编译为动态链接库(例如.so
文件用于Android,.dylib
文件用于iOS)。这里假设你已经有了一个简单的Rust库。
// libmy_rust_code.rs
#[no_mangle]
pub extern "C" fn hello_from_rust() -> *const u8 {
b"Hello from Rust!\0" as *const u8
}
编译这个Rust库为动态链接库,具体命令取决于你的操作系统和目标平台。
步骤四:集成Rust库到Flutter
Android
将编译好的.so
文件放到android/app/src/main/jniLibs/<abi>/
目录下,其中<abi>
是目标架构(如armeabi-v7a
, arm64-v8a
, x86
, x86_64
)。
在Flutter中,使用MethodChannel
来调用Rust函数:
import 'package:flutter/services.dart';
class NativeRustBridge {
static const MethodChannel _channel = MethodChannel('native_toolchain_rust_mirror');
static Future<String> getHelloFromRust() async {
final String result = await _channel.invokeMethod('helloFromRust');
return result;
}
}
在原生Android代码中(如MainActivity.kt
或MainActivity.java
),设置MethodChannel并处理来自Dart的调用:
// MainActivity.java
import android.os.Bundle;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "native_toolchain_rust_mirror";
@Override
public void configureFlutterEngine(FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
if (call.method.equals("helloFromRust")) {
// 调用Rust函数并返回结果
String hello = callRustFunction();
result.success(hello);
} else {
result.notImplemented();
}
}
);
}
private native String callRustFunction();
// 加载Rust库
static {
System.loadLibrary("my_rust_code");
}
}
iOS
将编译好的.dylib
文件添加到Xcode项目中,并确保它被正确链接。
在Flutter中,同样使用MethodChannel
来调用Rust函数(代码与Android相同)。
在原生iOS代码中(如AppDelegate.swift
或AppDelegate.m
),设置MethodChannel并处理来自Dart的调用:
// AppDelegate.swift
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "native_toolchain_rust_mirror", binaryMessenger: controller)
channel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) in
if call.method == "helloFromRust" {
let hello = self.callRustFunction()
result(hello)
} else {
result(FlutterMethodNotImplemented)
}
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func callRustFunction() -> String {
// 调用Rust函数并返回结果
// 注意:这里需要实现与Rust库的交互,可能涉及到桥接代码
return "Hello from Rust!" // 占位符,实际应调用Rust函数
}
}
注意事项
- Rust代码与Flutter的交互通常需要通过C接口进行,确保Rust函数使用
extern "C"
声明,并且避免名称修饰(name mangling)。 - 编译Rust库时,需要根据目标平台(Android, iOS)设置相应的编译目标。
- 在实际项目中,可能需要更复杂的桥接代码来处理数据传递和错误处理。
以上是一个概念性的示例,具体实现细节可能因项目需求和插件实现而异。务必参考native_toolchain_rust_mirror
插件的官方文档和示例代码。