Android与Flutter混合开发:页面跳转与通信完整指南
一、Android跳转Flutter页面的实现方式
1. 基础跳转方法
(1)使用全新引擎跳转(每次新建)
startActivity(
FlutterActivity
.withNewEngine()
.initialRoute("/home") // 指定Flutter初始路由
.build(context)
)
(2)使用缓存引擎(推荐,性能更优)
// Application中预初始化
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
val flutterEngine = FlutterEngine(this).apply {
dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
}
FlutterEngineCache.getInstance().put("default_engine", flutterEngine)
}
}
// 跳转时使用缓存引擎
startActivity(
FlutterActivity
.withCachedEngine("default_engine")
.initialRoute("/detail") // 可覆盖引擎初始路由
.build(context)
)
2. 参数传递方式
(1)通过路由传参
.initialRoute("/detail?id=123&name=flutter")
(2)通过Intent附加数据
FlutterActivity
.withNewEngine()
.build(context)
.apply {
putExtra("key", "value")
}
(3)通过MethodChannel实时通信
// Android端发送数据
MethodChannel(flutterEngine.dartExecutor, "data_channel").invokeMethod("initData", mapOf("key" to "value"))
// Flutter端接收
const channel = MethodChannel('data_channel');
channel.setMethodCallHandler((call) async {
if(call.method == "initData") {
print(call.arguments); // {key: value}
}
});
二、Flutter返回Android的实现方式
1. 基础返回
// 直接关闭当前FlutterActivity
Navigator.pop(context);
// 或使用系统级返回
SystemNavigator.pop();
2. 带参数返回
(1)通过MethodChannel
// Flutter端发送返回数据
const channel = MethodChannel('return_channel');
channel.invokeMethod('returnWithData', {'result': 'success'});
// Android端接收
MethodChannel(flutterEngine.dartExecutor, "return_channel").setMethodCallHandler { call, _ ->
if (call.method == "returnWithData") {
val result = call.argument<String>("result")
finish() // 关闭Activity
}
}
(2)通过startActivityForResult
// Android端启动
startActivityForResult(
FlutterActivity.withNewEngine().build(this),
REQUEST_CODE
)
// Flutter端触发返回
SystemNavigator.pop(animated: true);
// Android端接收结果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_CODE) {
// 处理返回数据
}
}
三、完整配置示例
1. AndroidManifest.xml
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" />
2. Flutter路由配置
void main() {
runApp(
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/detail': (context) => DetailPage(),
},
),
);
}
3. 跳转封装工具类
object FlutterRouter {
private const val ENGINE_ID = "default_engine"
fun init(application: Application) {
FlutterEngine(application).apply {
dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache.getInstance().put(ENGINE_ID, this)
}
}
fun open(context: Context, route: String, params: Map<String, Any>? = null) {
val intent = FlutterActivity
.withCachedEngine(ENGINE_ID)
.initialRoute(route)
.build(context)
params?.forEach { (key, value) ->
intent.putExtra(key, value.toString())
}
context.startActivity(intent)
(context as? Activity)?.overridePendingTransition(
R.anim.slide_in_right,
R.anim.slide_out_left
)
}
}
四、常见问题解决方案
问题现象 | 解决方案 |
---|---|
黑屏/白屏 | 设置backgroundMode(FlutterActivity.BackgroundMode.opaque) |
路由不生效 | 检查Flutter端MaterialApp 的路由表配置 |
内存泄漏 | 在onDestroy 中调用flutterEngine.destroy() |
返回键无效 | 使用WillPopScope 组件包裹Flutter页面 |
五、最佳实践建议
引擎管理
- 高频页面预加载多个引擎
- 低频页面使用
withNewEngine()
通信方式选择
- 简单数据:路由参数
- 复杂数据:MethodChannel
性能优化
- 添加跳转过渡动画
- 限制Flutter引擎的ABI架构
调试技巧
# 查看Flutter模块路由 flutter run --route=/debug # 检查混合栈状态 adb shell dumpsys activity activities
通过以上实现,可以构建稳定高效的混合页面导航系统