架构设计思路
- 分层架构
- 表现层:主要包含Flutter的UI部分,负责用户界面的展示和交互。这里的自定义
StatefulWidget
就处于此层。它通过与业务逻辑层交互,获取数据并更新UI。
- 业务逻辑层:处理应用的核心业务逻辑,不依赖于特定的平台。可以使用Flutter的
Bloc
(Business Logic Component)模式或者Provider
模式进行状态管理。这样可以将业务逻辑从UI中分离出来,提高代码的可维护性和可测试性。
- 平台层:包含原生Android或iOS代码。这一层负责与底层设备进行交互,提供一些Flutter无法直接实现的功能,如调用原生传感器、特定的系统API等。
- 通信桥梁:使用Flutter的
platform channels
作为Flutter与原生平台之间的通信桥梁。platform channels
允许Flutter与原生代码之间进行方法调用和数据传递。
- MethodChannel:用于在Flutter和原生平台之间进行异步方法调用。例如,Flutter可以通过
MethodChannel
调用原生代码中的某个方法来获取设备的唯一标识符。
- EventChannel:用于从原生平台向Flutter发送数据流。比如,原生代码检测到传感器数据变化时,可以通过
EventChannel
将数据实时传递给Flutter。
- BasicMessageChannel:用于在Flutter和原生平台之间传递消息,可以传递一些简单的数据类型,如字符串、整数等。
关键技术点
- Flutter与原生平台的通信
- 在Flutter端,通过
MethodChannel
、EventChannel
和BasicMessageChannel
类来与原生平台进行通信。例如,初始化MethodChannel
:
const platform = MethodChannel('com.example.app/native_method');
try {
final String result = await platform.invokeMethod('getNativeData');
// 处理返回结果
} on PlatformException catch (e) {
// 处理异常
}
- 在原生Android端,通过`flutter_plugin_android_lifecycle`库来注册方法通道,例如:
class MyPlugin implements MethodCallHandler {
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "com.example.app/native_method");
channel.setMethodCallHandler(new MyPlugin());
}
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getNativeData")) {
String nativeData = "Some native data";
result.success(nativeData);
} else {
result.notImplemented();
}
}
}
- 在原生iOS端,通过`FlutterPlugin`来注册方法通道,例如:
import Flutter
import UIKit
public class SwiftMyPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "com.example.app/native_method", binaryMessenger: registrar.messenger())
let instance = SwiftMyPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
if call.method == "getNativeData" {
let nativeData = "Some native data"
result(nativeData)
} else {
result(FlutterMethodNotImplemented)
}
}
}
- 状态管理
- Bloc模式:创建
Bloc
类来管理业务逻辑和状态。例如,创建一个CounterBloc
:
import 'package:bloc/bloc.dart';
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0);
@override
Stream<int> mapEventToState(CounterEvent event) async* {
if (event is IncrementEvent) {
yield state + 1;
} else if (event is DecrementEvent) {
yield state - 1;
}
}
}
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
- **Provider模式**:通过`Provider`来提供状态数据。例如:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
void decrement() {
_count--;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CounterModel(),
child: MyApp(),
)
);
}
设计模式
- MVC(Model - View - Controller)模式:虽然Flutter本身的架构与传统的MVC有所不同,但可以借鉴其思想。
StatefulWidget
可以看作是View
,业务逻辑部分(如使用Bloc
或Provider
管理的部分)可以看作是Model
,而platform channels
的交互逻辑可以看作是Controller
,负责协调View
和Model
之间以及与原生平台的交互。
- Facade模式:在原生平台代码中,可以使用Facade模式。将复杂的原生功能封装在一个简单的接口后面,使得Flutter端调用原生功能时更加简洁。例如,将多个传感器相关的原生方法封装在一个
SensorFacade
类中,Flutter端只需要调用SensorFacade
提供的简单方法即可获取所需的传感器数据。