Flutter原生功能调用插件dart_native_annoy的使用

Flutter原生功能调用插件dart_native_annoy的使用

dart_native_annoy

dart_native_annoy 是一个用于在 Flutter 中调用 Rust 编写的 annoy 库的插件。annoy 是 Spotify 开发的一个用于近似最近邻搜索的库。

安装与配置

首先,确保你的项目已经集成了 dart_native_annoy 插件。你可以在 pubspec.yaml 文件中添加以下依赖:

dependencies:
  dart_native_annoy: ^版本号

然后执行 flutter pub get 来安装依赖。

使用示例

以下是一个完整的示例,展示如何使用 dart_native_annoy 进行近似最近邻搜索。

示例代码

import 'dart:ffi';
import 'package:dart_native_annoy/annoy.dart';

void main() {
  // 创建工厂实例,加载动态库
  final fac = AnnoyIndexFactory(lib: DynamicLibrary.open('libru_annoy.so'));

  // 加载预训练的索引文件
  final index = fac.loadIndex(
    'index.euclidean.5d.ann',  // 索引文件名
    5,                         // 向量维度
    IndexType.Euclidean        // 距离度量类型
  )!;

  // 输出索引大小
  print('size: ${index.size}');

  // 获取某个向量
  final v3 = index.getItemVector(3);

  // 获取最近的 5 个邻居,并包含距离信息
  final nearest = index.getNearest(v0, 5, includeDistance: true);

  // 打印结果
  print('nearest neighbors: $nearest');
}

解释

  1. 导入必要的库

    • dart:ffi:用于与本地代码交互。
    • dart_native_annoy/annoy.dart:插件的核心类。
  2. 创建工厂实例

    • 使用 DynamicLibrary.open 加载本地动态库 libru_annoy.so
  3. 加载索引文件

    • loadIndex 方法用于加载预训练的索引文件,指定文件名、向量维度和距离度量类型。
  4. 获取向量

    • 使用 getItemVector 方法获取特定索引位置的向量。
  5. 获取最近邻

    • getNearest 方法用于获取最近的邻居,可以指定邻居数量并选择是否包含距离信息。

构建本地库

要使用 dart_native_annoy,你需要构建本地库 libru_annoy.so。以下是构建步骤:

  1. 安装 Rust

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
  2. 克隆并进入 RuAnnoy 仓库

    git clone https://github.com/hanabi1224/RuAnnoy.git
    cd RuAnnoy
    
  3. 构建本地库

    cargo build --release --all-features
    
  4. 交叉编译(可选): 如果你需要为不同的平台生成库,可以使用以下命令:

    cargo lipo --release --targets=aarch64-apple-ios,x86_64-apple-ios,armv7-apple-ios,armv7s-apple-ios
    cargo build --target aarch64-linux-android --release
    cargo build --target armv7-linux-androideabi --release
    cargo build --target i64-linux-android --release
    

构建完成后,本地库会出现在 target/release 目录下,分别是 libru_annoy.soru_annoy.dlllibru_annoy.dylib

单元测试

你可以运行单元测试来验证插件的功能:

pub get && dart run test

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

1 回复

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


dart_native_annoy 是一个用于在 Flutter 中调用原生功能的插件。它允许你在 Flutter 应用中直接调用 Android 和 iOS 的原生代码,而不需要编写复杂的平台通道代码。以下是如何使用 dart_native_annoy 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 dart_native_annoy 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  dart_native_annoy: ^0.0.1  # 使用最新的版本号

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

2. 创建原生代码

Android

在 Android 项目中,你可以创建一个原生方法,并通过 dart_native_annoy 插件在 Flutter 中调用它。

  1. android/app/src/main/java/com/example/your_app/ 目录下创建一个新的 Java 类,例如 NativeMethods.java
package com.example.your_app;

public class NativeMethods {
    public static String getNativeMessage() {
        return "Hello from Android Native Code!";
    }
}
  1. MainActivity.java 中注册这个类:
import com.dartnative.annoy.Annoy;
import com.example.your_app.NativeMethods;

public class MainActivity extends FlutterActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Annoy.register("NativeMethods", NativeMethods.class);
    }
}

iOS

在 iOS 项目中,你可以创建一个原生方法,并通过 dart_native_annoy 插件在 Flutter 中调用它。

  1. ios/Runner/ 目录下创建一个新的 Objective-C 类,例如 NativeMethods.m
#import <Foundation/Foundation.h>

@interface NativeMethods : NSObject

+ (NSString *)getNativeMessage;

@end

@implementation NativeMethods

+ (NSString *)getNativeMessage {
    return @"Hello from iOS Native Code!";
}

@end
  1. AppDelegate.m 中注册这个类:
#import "AppDelegate.h"
#import "NativeMethods.h"
#import <dart_native_annoy/dart_native_annoy.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [Annoy registerClass:[NativeMethods class]];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

3. 在 Flutter 中调用原生代码

在 Flutter 中,你可以使用 dart_native_annoy 插件调用刚刚创建的原生方法。

import 'package:flutter/material.dart';
import 'package:dart_native_annoy/dart_native_annoy.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Native Example'),
        ),
        body: Center(
          child: FutureBuilder<String>(
            future: callNativeMethod(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return CircularProgressIndicator();
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                return Text('Native Message: ${snapshot.data}');
              }
            },
          ),
        ),
      ),
    );
  }

  Future<String> callNativeMethod() async {
    try {
      final result = await Annoy.invokeStaticMethod('NativeMethods', 'getNativeMessage');
      return result.toString();
    } catch (e) {
      return 'Failed to invoke native method: $e';
    }
  }
}
回到顶部