Flutter多功能集成插件one_for_all的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter多功能集成插件one_for_all的使用

OneForAll 是一个代码生成工具,旨在使 Flutter 和宿主平台之间的通信更加类型安全、简单和快速。

OneForAll 去除了在多个平台和语言之间管理字符串的必要性。它还提高了常见的方法通道模式的效率。最重要的是,它消除了编写自定义平台通道代码的需求,因为 OneForAll 可以为您生成这些代码。

特性

支持的平台

目前,one_for_all 支持生成:

  • Dart
  • Android 的 Kotlin 代码
  • iOS 和 macOS 的 Swift 代码

开始使用

在您的 pubspec.yaml 文件中添加以下依赖项:

dependencies:
  one_for_all:
dev_dependencies:
  one_for_all_generator:

使用方法

  1. 使用 @HostApi() 注解一个类。
  2. 添加一个返回 Future 的抽象方法。
  3. 扩展生成的类:
@HostApi()
class Terminal extends _$Terminal {
  Future<List<Reader>> fetchReaders();
}
  1. 生成代码:
  • 默认脚本
dart run one_for_all_generator \
  --api-path=lib/terminal.dart \
  --kotlin-output-file=android/src/main/Terminal.kt \
  --kotlin-package=com.terminal
  --swift-output-file=ios/Classes/Terminal.swift
  • 自定义脚本
import 'package:one_for_all_generator/one_for_all_generator.dart';

void main() async {
  await OneForAll.from(
    options: const OneForAllOptions(
      apiFile: 'lib/terminal.dart',
    ),
    dartOptions: const DartOptions(),
    kotlinOptions: const KotlinOptions(
      outputFile: 'android/src/main/Terminal.kt',
      package: 'com.terminal',
    ),
    swiftOptions: const SwiftOptions(
      outputFile: 'ios/Classes/Terminal.swift',
    ),
  ).build();
}

生成方法为异步、同步或使用回调

您可以使用 @MethodApi 注解来以三种不同的方式生成原生方法:

@HostApi()
class Terminal extends _$Terminal {
  @MethodApi(
    kotlin: MethodApiType.&lt;sync|async|callbacks&gt;
    swift: MethodApiType.&lt;sync|async|callbacks&gt;,
  )
  Future<List<Reader>> fetchReaders();
}
  • sync: 需要实现的方法将具有与 Dart 方法相同的参数,并且返回类型与 Dart 中的 Future 相同。
  • callbacks: 允许正常使用通道。需要实现的方法的第一个参数是一个带有已实现序列化的 Result,其余参数与 Dart 中的方法相同。该方法不返回任何内容。
  • async: 需要实现的方法将具有与 Dart 中相同的参数,但在 Kotlin 中它将是一个 suspend 方法,在 Swift 中则是一个 async 方法。返回类型与 Dart 中的 Future 相同。

是否需要从原生代码调用 Flutter 方法?

定义自己的类,其中包含要在各个平台上可用的方法并实现它们。方法必须以 on_on 开头。

@FlutterApi()
class _FlutterTerminal {
  Future<String> onFetchToken() async {
    return await httpClient.getToken();
  }
}

连接通道到您的实现:

final flutterTerminal = _FlutterTerminal();
setupFlutterTerminal(flutterTerminal);

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

1 回复

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


当然,one_for_all 是一个假设的 Flutter 插件名称,用于说明多功能集成的概念。在现实中,可能没有这样一个具体名为 one_for_all 的官方插件,但我们可以基于常见的 Flutter 插件集成方式来模拟一个多功能插件的使用案例。

假设 one_for_all 插件集成了以下功能:

  1. 网络请求(HTTP Client)
  2. 本地存储(SQLite/SharedPreferences)
  3. 图片选择器(Image Picker)
  4. 设备信息获取(Device Info)

下面是一个简化的代码示例,展示如何在 Flutter 项目中使用这些功能。为了模拟 one_for_all 插件,我们将分别使用 http, sqflite, image_picker, 和 device_info 插件。

首先,确保在 pubspec.yaml 文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3
  sqflite: ^2.0.0+4
  path_provider: ^2.0.2
  image_picker: ^0.8.4+3
  device_info: ^2.0.2

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

接下来,在 main.dart 文件中实现这些功能:

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:image_picker/image_picker.dart';
import 'package:device_info/device_info.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ImagePicker _picker = ImagePicker();

  Future<void> _makeNetworkRequest() async {
    final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
    if (response.statusCode == 200) {
      print('Network request successful: ${response.body}');
    } else {
      throw Exception('Failed to load post');
    }
  }

  Future<void> _saveToLocalStorage() async {
    final directory = await getApplicationDocumentsDirectory();
    final path = '${directory.path}/example.db';

    final db = await openDatabase(path, version: 1, onCreate: (Database db, int version) async {
      await db.execute('CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT)');
    });

    await db.insert('Test', {'name': 'Flutter'}, conflictAlgorithm: ConflictAlgorithm.replace);
    print('Data saved to local storage');

    db.close();
  }

  Future<File?> _pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      print('Image picked: ${pickedFile.path}');
      return pickedFile;
    } else {
      print('No image selected');
    }
    return null;
  }

  Future<void> _getDeviceInfo() async {
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    if (Platform.isAndroid) {
      AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
      print('Device Brand: ${androidInfo.brand}');
      print('Device Model: ${androidInfo.model}');
    } else if (Platform.isIOS) {
      IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
      print('Device Name: ${iosInfo.name}');
      print('Device System Name: ${iosInfo.systemName}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('One for All Plugin Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _makeNetworkRequest,
              child: Text('Make Network Request'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _saveToLocalStorage,
              child: Text('Save to Local Storage'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _getDeviceInfo,
              child: Text('Get Device Info'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们展示了如何使用不同的 Flutter 插件来执行网络请求、保存到本地存储、选择图片以及获取设备信息。这些功能被集成到一个 Flutter 应用中,用户可以通过点击按钮来触发相应的操作。

请注意,这个示例仅用于演示目的,实际项目中可能需要更复杂的错误处理和状态管理。

回到顶部