Flutter原生方法通信插件action_channel的使用
Flutter原生方法通信插件action_channel的使用
概述
action_channel
插件是一个方便的功能包装器,它将一个 sink 和一个 stream 结合在一起。该插件允许输入/接收类型与输出/发送类型不同,并且可以处理回复,使其可用作请求-响应通道。
特性
- 允许输入/接收类型与输出/发送类型不同,简化入口点。
- 处理“回复”,使其可用作请求-响应通道。
- 当接收到某些数据时,可以运行特定操作。
安装
在 pubspec.yaml
文件中添加依赖项:
dependencies:
action_channel: ^x.x.x
然后在 Dart 文件中导入包:
import 'package:action_channel/action_channel.dart';
使用
创建通道
你可以通过 sink 和 stream 创建一个通道。你还可以指定一个动作,当调用 .on()
方法时,该动作会使用返回的数据执行。
final channel = Channel(
sink,
stream,
action: (String data) => print('Action using "$data"')
);
监听数据
你可以使用 .on()
方法监听通道,这将使你能够运行一个动作并使用返回的数据,就像一个“回复”。
final subscription = channel.on((data) {
print('Data received "$data"');
return 'New action using "$data"';
});
// 取消订阅
subscription.cancel();
你也可以使用 .once()
方法来监听通道仅一次。
channel.once((data) {
print('First data: "$data"');
});
注意:
通道可以用作流,使用 .listen()
方法。
通道控制器
创建通道时可以使用 ChannelController
,它自身处理 sink 和 stream 的创建,从而抽象出 sink 和 stream 的创建过程。控制器需要一个函数,该函数将输入/接收数据类型转换为输出/发送数据类型。
推荐使用 Channel.controller()
工厂方法,它会自动创建一个 ChannelController
。
final channel = Channel<int, String, void>.controller(
(int id) => User(id),
);
// 带有回调的控制器
final channel = Channel<int, String, void>.controller(
(int id) => User(id),
onAdded: (int id) => print('User $id added'),
onData: (User user) => print('User with id "${ user.id }" received'),
onListen: (subscription) => print('Channel listened'),
onClose: () => print('Channel closed'),
);
示例
以下是一个完整的示例,展示了如何使用 action_channel
插件。
import 'package:action_channel/action_channel.dart';
final users = <User>{
User(1, 'John'),
User(2, 'Tom', muted: true),
User(3, 'Alex'),
};
void main() {
final channel = Channel<int, User, String>.controller(
(id) => users.firstWhere((user) => user.id == id),
action: (message, user, channel) => user.say(message),
);
// 过滤非静音用户并监听数据
channel.where((user) => !user.muted).on((user) => 'Hello!');
// 监听一次数据
channel.once((data) {
print('First user: ${data.name}');
return null;
});
// 添加用户
channel.add(1);
channel.add(2);
channel.add(3);
}
/* -= Models =- */
class User {
final int id;
final String name;
final bool muted;
User(this.id, this.name, { this.muted = false });
void say(String message) => print('User $id says "$message"');
}
更多关于Flutter原生方法通信插件action_channel的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter原生方法通信插件action_channel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用action_channel
(通常指的是MethodChannel
,因为Flutter
并没有一个官方名为action_channel
的插件,但概念上是类似的)进行原生方法通信的代码案例。
Flutter 端代码
首先,在你的Flutter项目中创建一个Dart文件来定义与原生平台通信的接口。假设我们创建一个名为platform_channel.dart
的文件:
import 'package:flutter/services.dart';
class PlatformChannel {
static const MethodChannel _channel = const MethodChannel('com.example.yourapp/platform_channel');
static Future<String?> getPlatformVersion() async {
final String? version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}
然后,在你的Flutter组件中调用这个接口:
import 'package:flutter/material.dart';
import 'platform_channel.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Platform Channel Example'),
),
body: Center(
child: FutureBuilder<String?>(
future: PlatformChannel.getPlatformVersion(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
return Text('Platform Version: ${snapshot.data ?? 'Unknown'}');
} else {
return CircularProgressIndicator();
}
},
),
),
),
);
}
}
原生 Android 端代码
接下来,在你的Android项目中处理来自Flutter的调用。假设你的Flutter项目已经集成了Android平台。
在MainActivity.kt
(或MainActivity.java
,如果你使用的是Java)中添加以下代码:
Kotlin 版本
package com.example.yourapp
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.example.yourapp/platform_channel"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
}
}
}
}
Java 版本
package com.example.yourapp;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
import android.os.Build;
import android.os.Bundle;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "com.example.yourapp/platform_channel";
@Override
public void configureFlutterEngine(FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
if (call.method.equals("getPlatformVersion")) {
String platformVersion = "Android " + Build.VERSION.RELEASE;
result.success(platformVersion);
} else {
result.notImplemented();
}
}
);
}
}
原生 iOS 端代码
最后,在你的iOS项目中处理来自Flutter的调用。假设你的Flutter项目已经集成了iOS平台。
在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: "com.example.yourapp/platform_channel", binaryMessenger: controller)
channel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) in
if call.method == "getPlatformVersion" {
let version = UIDevice.current.systemVersion
result(version)
} else {
result(FlutterMethodNotImplemented)
}
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
这就是一个完整的示例,展示了如何在Flutter与原生平台(Android和iOS)之间通过MethodChannel
进行通信。你可以根据需要扩展这个示例来处理更多的方法调用和数据传输。