如何在Flutter原生Android代码中实现MVVM架构并使用ViewModel与LiveData?
嘿,我刚好在Flutter Android插件里落地过MVVM架构,给你梳理下完整的实现步骤,亲测能顺畅对接ViewModel和LiveData:
在Flutter Android平台端/插件中实现MVVM架构
1. 先配置Android端依赖
首先在Android模块的build.gradle(Module级别)里添加ViewModel和LiveData的依赖,Flutter默认项目一般没包含这些:
dependencies { // ViewModel + LiveData核心依赖 implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2" // Kotlin扩展(Java项目可去掉-ktx后缀) implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2" }
2. 实现ViewModel与LiveData
这里以Kotlin为例(Java写法逻辑一致),写一个带业务逻辑的ViewModel,用LiveData承载要传递给Flutter的数据:
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch class PluginViewModel : ViewModel() { // 用于向Flutter层推送数据的LiveData val nativeDataResult = MutableLiveData<String>() // 模拟原生耗时业务操作(比如调用Android系统API、数据库查询等) fun executeNativeBusiness(param: String) { viewModelScope.launch(Dispatchers.IO) { // 替换成你的实际业务逻辑 Thread.sleep(1500) val processedResult = "原生处理完成:参数[$param]" // 切回主线程更新LiveData(LiveData的setValue必须在主线程) launch(Dispatchers.Main) { nativeDataResult.value = processedResult } } } }
3. 在Flutter插件中关联ViewModel与LiveData
在你的插件核心类里,初始化ViewModel并监听LiveData变化,把结果回调给Flutter:
import androidx.lifecycle.ViewModelProvider import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel class MyNativePlugin : FlutterPlugin, MethodChannel.MethodCallHandler { private lateinit var channel: MethodChannel private lateinit var viewModel: PluginViewModel override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { channel = MethodChannel(binding.binaryMessenger, "native_mvvm_channel") channel.setMethodCallHandler(this) // 初始化ViewModel,用插件绑定的ApplicationContext获取实例 viewModel = ViewModelProvider( ViewModelProvider.AndroidViewModelFactory.getInstance(binding.applicationContext) )[PluginViewModel::class.java] // 监听LiveData,有数据变化时回调给Flutter viewModel.nativeDataResult.observeForever { result -> channel.invokeMethod("onNativeDataReady", mapOf("result" to result)) } } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { "startNativeTask" -> { val param = call.argument<String>("input") ?: "" // 调用ViewModel的业务方法 viewModel.executeNativeBusiness(param) result.success("原生任务已启动") } else -> result.notImplemented() } } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { channel.setMethodCallHandler(null) // 移除LiveData观察者,避免内存泄漏 viewModel.nativeDataResult.removeObserver {} } }
4. Flutter层的调用与数据接收
在Dart代码里通过MethodChannel调用原生方法,并监听原生回调:
import 'package:flutter/services.dart'; class NativeMvvmManager { static const MethodChannel _channel = MethodChannel('native_mvvm_channel'); static Function(String)? onDataReceived; static void init() { _channel.setMethodCallHandler((call) async { if (call.method == 'onNativeDataReady') { final String result = call.arguments['result']; onDataReceived?.call(result); } return null; }); } static Future<String?> startNativeTask(String input) async { final String? response = await _channel.invokeMethod('startNativeTask', {'input': input}); return response; } }
在页面中使用示例:
@override void initState() { super.initState(); NativeMvvmManager.init(); NativeMvvmManager.onDataReceived = (result) { // 处理原生返回的结果 print("收到原生数据:$result"); }; } // 触发原生任务 void _triggerNativeTask() { NativeMvvmManager.startNativeTask("来自Flutter的请求参数"); }
5. 关键注意事项
- 内存泄漏防范:插件脱离引擎时一定要移除LiveData的永久观察者;如果你的插件是
ActivityAware类型,可以绑定Activity生命周期来观察LiveData,比observeForever更安全。 - 线程规范:ViewModel里的耗时操作必须放在子线程,LiveData的
setValue必须在主线程,用viewModelScope管理协程是最省心的方式。 - Java兼容:如果用Java开发插件,ViewModel初始化要写成
new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(PluginViewModel.class),LiveData的监听和移除逻辑和Kotlin一致。
内容的提问来源于stack exchange,提问作者Harish
相关产品推荐
相关产品推荐

