You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:49:07