如何区分Flutter代码是由原生项目还是纯Flutter项目启动?
可行的实现方案
以下几种方案可以帮你区分Flutter代码是由iOS原生项目启动,还是由纯Flutter的main.dart直接启动,且不会污染全局SDK或其他项目:
方案一:原生侧传递启动标识(最准确)
在iOS原生创建FlutterViewController时,通过初始化参数或MethodChannel向Flutter侧传递启动来源标识,Flutter侧读取该标识即可区分。
iOS原生代码示例
方式1:通过initialRoute传递
// 原生创建FlutterViewController时 FlutterViewController *flutterVC = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil]; // 自定义路由作为启动标识,纯Flutter启动时默认是空字符串或"/" flutterVC.initialRoute = @"native_launch";
方式2:通过MethodChannel传递
FlutterViewController *flutterVC = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil]; FlutterMethodChannel *launchChannel = [FlutterMethodChannel methodChannelWithName:@"com.your.app/launch_source" binaryMessenger:flutterVC.binaryMessenger]; // 向Flutter发送启动来源 [launchChannel invokeMethod:@"setSource" arguments:@"native"];
Flutter侧代码示例
对应方式1:读取initialRoute
void main() { WidgetsFlutterBinding.ensureInitialized(); // 获取默认路由,纯Flutter启动时默认是"/"或空字符串 final String initialRoute = WidgetsBinding.instance.window.defaultRouteName; final bool isNativeLaunch = initialRoute == "native_launch"; runApp(MyApp(isNativeLaunch: isNativeLaunch)); }
对应方式2:通过MethodChannel接收
import 'package:flutter/services.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); bool isNativeLaunch = false; const MethodChannel _channel = MethodChannel("com.your.app/launch_source"); try { // 尝试获取原生传递的标识,纯Flutter启动时会抛出异常 final String? source = await _channel.invokeMethod("getSource"); isNativeLaunch = source == "native"; } on PlatformException { // 捕获异常说明是纯Flutter启动 isNativeLaunch = false; } runApp(MyApp(isNativeLaunch: isNativeLaunch)); }
方案二:项目级环境变量配置(无需修改原生代码)
在Android Studio的Flutter运行配置中,为纯Flutter启动设置项目专属环境变量,Flutter侧读取该变量即可区分,不会影响全局SDK或其他项目。
配置步骤
- 打开Android Studio的
Run > Edit Configurations - 选择你的Flutter运行配置,切换到
Environment Variables标签 - 添加变量:
LAUNCH_SOURCE=flutter,点击保存
Flutter侧代码示例
import 'dart:io'; void main() { WidgetsFlutterBinding.ensureInitialized(); // 纯Flutter启动时该变量存在,原生启动时不存在 final bool isNativeLaunch = Platform.environment['LAUNCH_SOURCE'] != 'flutter'; runApp(MyApp(isNativeLaunch: isNativeLaunch)); }
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 原生传递标识 | 结果准确,无歧义 | 需要修改iOS原生代码 |
| 项目级环境变量 | 无需修改原生代码,配置简单 | 依赖Android Studio运行配置,若原生侧也设置该变量会产生混淆(概率极低) |
内容的提问来源于stack exchange,提问作者ximmyxiao
相关产品推荐
相关产品推荐

