flowchart LR
subgraph agent["Agent(IDE / CLI)"]
A[对话与计划]
end
subgraph mcp["MCP 服务"]
G[Git / 文件]
B[构建与日志]
L[Lint / 测试]
D[需求与文档]
end
subgraph repo["工程仓库"]
R[Android / iOS / Harmony 模块]
end
A --> G
A --> B
A --> L
A --> D
G --> R
B --> R
L --> R
转换落地之后,仍然需要人按需求自己多走几遍:主路径、边界条件、各端差异(权限、后台、埋点)往往要手动点一点才暴露。这里不必讳言——人工走查仍是验收的一环。差别在于:一旦发现问题,把报错、堆栈、复现步骤丢回给 AI,在 MCP 能读到工程上下文的前提下,修一轮的成本明显低于从零手改。整体仍是:大功能先转过去 → 人按需求验收 → 卡点再交给 AI 迭代,提效很多,但预期是「加速器」,不是「免验收」。
3. 转换工作流建议(可落地的一版)
下面是一条在团队里较容易推广的最小闭环,可按你们 CI 成熟度裁剪。
flowchart TB
Q[对齐需求与范围] --> S[建立对照表:模块/接口/平台差异]
S --> T[分支策略:按端或按业务垂直切]
T --> C[大功能点互转 + 本地构建]
C --> H[人按需求走查多遍]
H -->|发现问题| F[把现象与日志交给 AI 修复]
F --> C
H -->|通过| V[门禁:Skill 清单跑一遍]
V -->|不通过| C
V -->|通过| P[PR:说明对照与风险]
overridefunconfigureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel( flutterEngine.dartExecutor.binaryMessenger, CHANNEL ).setMethodCallHandler { call, result -> when (call.method) { "getBatteryLevel" -> { val level = getBatteryLevel() if (level != -1) { result.success(level) } else { result.error("UNAVAILABLE", "Battery level not available.", null) } } else -> result.notImplemented() } } }
privatefungetBatteryLevel(): Int { val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) } }
sequenceDiagram
participant D as Dart 业务层
participant C as MethodChannel
participant E as Flutter Engine
participant N as 原生 Android / iOS
D->>C: invokeMethod(name, args)
C->>E: 序列化 StandardMessageCodec
E->>N: 平台通道分发
N-->>E: 返回值 / 错误
E-->>C: 反序列化
C-->>D: Future 完成
sequenceDiagram
participant D as Dart send / setMessageHandler
participant B as BasicMessageChannel
participant N as 原生 MessageHandler
D->>B: send(message)
B->>N: 投递消息
N->>N: 处理并可构造响应
N-->>B: reply.reply(response)
B-->>D: Future 或回调
staticvoid _recordMetric(String channelName, int duration) { if (!_metrics.containsKey(channelName)) { _metrics[channelName] = []; } _metrics[channelName]!.add(duration); if (_metrics[channelName]!.length > _maxMetrics) { _metrics[channelName]!.removeAt(0); } if (duration > 100) { debugPrint('⚠️ Slow channel call: $channelName took ${duration}ms'); } }
staticMap<String, dynamic> getMetrics() { return _metrics.map((name, durations) => MapEntry( name, { 'avg': durations.reduce((a, b) => a + b) / durations.length, 'max': durations.reduce((a, b) => a > b ? a : b), 'min': durations.reduce((a, b) => a < b ? a : b), }, )); } }
sequenceDiagram
participant F as Flutter BasicMessageChannel
participant N as 原生 Receiver
F->>N: type=metadata(文件名、大小、块数)
loop 每个分块
F->>N: type=chunk(index, data)
N->>N: 追加到缓冲区
end
F->>N: type=complete
N->>N: 合并写入磁盘
flowchart LR
subgraph control["MethodChannel(控制)"]
C1["connect / disconnect / sendData"]
end
subgraph events["EventChannel(下行数据)"]
E1["receiveBroadcastStream"]
end
Native["原生实时服务"] --> events
control <--> Native
flowchart LR
App["Dart 业务参数"] --> Enc["加密"]
Enc --> MC["MethodChannel"]
MC --> Native["原生解密/处理"]
Native --> Resp["加密响应"]
Resp --> MC
MC --> Dec["Dart 解密"]
Dec --> App
// 加密服务 classCryptoService{ final _key = 'your-secret-key-32-bytes-long'; final _iv = '16-bytes-initial-vec';
Future<String> encrypt(String plaintext) async { final key = Key.fromUtf8(_key); final iv = IV.fromUtf8(_iv); final encryptor = Encrypter(AES(key, mode: AESMode.cbc)); final encrypted = encryptor.encrypt(plaintext, iv: iv); return encrypted.base64; }
Future<String> decrypt(String ciphertext) async { final key = Key.fromUtf8(_key); final iv = IV.fromUtf8(_iv); final encryptor = Encrypter(AES(key, mode: AESMode.cbc)); final decrypted = encryptor.decrypt64(ciphertext, iv: iv); return decrypted; } }
六、工程化与团队协作
6.1 项目结构
仓库分层关系(简化):
flowchart TB
subgraph mobile["原生工程"]
A["android/"]
I["ios/"]
end
subgraph flutter["Flutter 工程"]
L["lib/"]
M["main.dart"]
end
subgraph shared["可选共享"]
S["shared/"]
end
subgraph docs["文档"]
D["docs/"]
end
mobile --- L
L --- M
shared -.-> L
docs -.-> mobile
docs -.-> L
static Future<bool> checkCompatibility() async { final platform = Theme.of(Get.context!).platform; switch (platform) { case TargetPlatform.android: return await _checkAndroidVersion(); case TargetPlatform.iOS: return await _checkIOSVersion(); default: return false; } }
static Future<bool> _checkAndroidVersion() async { final channel = MethodChannel('com.example.device/info'); final version = await channel.invokeMethod<int>('getAndroidVersion'); return version != null && version >= _minAndroidVersion; }
static Future<bool> _checkIOSVersion() async { final channel = MethodChannel('com.example.device/info'); final version = await channel.invokeMethod<String>('getIOSVersion'); return version != null && version.compareTo(_minIOSVersion) >= 0; } }
七、故障排查与性能分析
排查思路总览(可先自上而下缩小范围):
flowchart TD
Start["Channel / 混合页面异常"] --> A{"调用无响应或超时?"}
A -->|是| T["withTimeout + 日志定位哪一侧阻塞"]
A -->|否| B{"PlatformException?"}
B -->|是| P["核对 method 名、参数类型、是否 notImplemented"]
B -->|否| C{"内存持续增长?"}
C -->|是| M["检查 Stream/EventChannel 是否 cancel、引擎是否泄漏"]
C -->|否| D["使用性能监控与 Profiler 采集 Channel 耗时分布"]
final avgTime = _callTimes.reduce((a, b) => a + b) / _callTimes.length; final maxTime = _callTimes.reduce((a, b) => a > b ? a : b); final minTime = _callTimes.reduce((a, b) => a < b ? a : b);