Flutter——最详细原生交互(MethodChannel、EventChannel、BasicMessageChannel)使用教程

  1. MethodChannel(方法通道)
    用途:实现 双向通信,用于调用原生平台提供的 API 并获取返回结果。
    场景:适合一次性操作,如调用相机、获取设备信息等。

使用步骤:

  • Flutter 端:通过 MethodChannel监听事件流。
dart 复制代码
  static const platform =
      MethodChannel('com.example.fltest.plugin.DeviceInfoPlugin');
  • Android 端(Kotlin)
kotlin 复制代码
    private var methodChannel: MethodChannel? = null
  val CHANNEL: String = "com.example.fltest.plugin.DeviceInfoPlugin"
  
  private fun getPhoneNumber(): Any? {
        val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager?
//        val phoneNumber = telephonyManager!!.line1Number
        val phoneNumber = "18627000332"
        return phoneNumber
    }
  1. EventChannel(事件通道)
    用途:实现 单向数据流,用于原生平台向 Flutter 持续发送事件(如传感器数据)。
    场景:适合实时数据流,如监听陀螺仪、GPS 位置更新等。
    使用步骤:
  • Flutter 端:通过 EventChannel 监听事件流。
dart 复制代码
static const eventChannel =
      EventChannel('com.example.fltest.plugin.DeviceInfoPlugin/event');

  Stream<int> get _batteryLevelStream {
    return eventChannel.receiveBroadcastStream("111").cast<int>();
  }
  • Android 端(Kotlin)
kotlin 复制代码
 
class DeviceInfoPlugin(var context: Context) : EventChannel.StreamHandler, FlutterPlugin {

    private var eventChannel: EventChannel? = null
    val EVENT_CHANNEL: String = "com.example.fltest.plugin.DeviceInfoPlugin/event"

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
            result.notImplemented()
    }

    override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        setupChannels(binding.binaryMessenger, binding.applicationContext)
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        teardownChannels()
    }

    private fun setupChannels(messenger: BinaryMessenger, context: Context) {
        this.context = context
        eventChannel = EventChannel(messenger, EVENT_CHANNEL)
        eventChannel?.setStreamHandler(this)
    }

    private fun teardownChannels() {
        eventChannel?.setStreamHandler(null)
        eventChannel = null
    }

    private val mainHandler = Handler(Looper.getMainLooper())

    override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
        Toast.makeText(context, arguments.toString(), Toast.LENGTH_SHORT).show()
        events?.let {
            sendBatteryLevel(it)
            events.success(1)
            mainHandler.postDelayed({
                events.success(2)
            }, 2000)
            mainHandler.postDelayed({ events.success(3) }, 4000)
        }
    }

    override fun onCancel(arguments: Any?) {

    }

    private fun sendBatteryLevel(events: EventChannel.EventSink) {
        val batteryLevel = -1
        if (batteryLevel != -1) {
            events.success(batteryLevel)
        } else {
            events.error("UNAVAILABLE", "Battery level not available.", null);
        }
    }
}
  1. BasicMessageChannel(基础消息通道)
    用途:支持 异步消息传递,使用自定义编解码器传递数据。
    场景:适合简单的数据交换(如 JSON、二进制数据)。

使用步骤:

  • Flutter 端:通过 BasicMessageChannel监听事件流。
dart 复制代码
  final BasicMessageChannel<String> messageChannel =
      BasicMessageChannel<String>(
    'com.example.fltest.plugin.DeviceInfoPlugin/basicMessage',
    StringCodec(),
  );
  
// 发送消息
Future<String> sendMessage(String message) async {
  return await messageChannel.send(message);
}

    @override
  void initState() {
    super.initState();
    // 设置消息处理器
    messageChannel.setMessageHandler((String? message) async {
      print('Received message from native: $message');
      return '$message';
    });
  }
  
  • Android 端(Kotlin)
kotlin 复制代码
package com.example.fltest.plugin

import android.content.Context
import android.os.Handler
import android.os.Looper
import android.telephony.TelephonyManager
import android.widget.Toast
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.BasicMessageChannel.Reply
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.common.StringCodec


class DeviceInfoPlugin(var context: Context) :  FlutterPlugin {

    private var basicMessageChannel: BasicMessageChannel<String>? = null
    val BASIC_MESSAGE_CHANNEL: String = "com.example.fltest.plugin.DeviceInfoPlugin/basicMessage"

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
      
            result.notImplemented()
       
    }

    override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        setupChannels(binding.binaryMessenger, binding.applicationContext)
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        teardownChannels()
    }

    private fun setupChannels(messenger: BinaryMessenger, context: Context) {
        this.context = context
        basicMessageChannel = BasicMessageChannel(messenger, BASIC_MESSAGE_CHANNEL, StringCodec.INSTANCE)
        basicMessageChannel?.setMessageHandler { message, reply ->
            println("Received message from Flutter: $message")
            reply.reply("Message received")
            basicMessageChannel?.send(message
            ) { reply -> Toast.makeText(context, reply.toString(), Toast.LENGTH_SHORT).show() }
        }
        // 发送消息
basicMessageChannel.send("Hello from Android") { reply ->
    Log.d("TAG", "Reply: $reply")
}
    }

    private fun teardownChannels() {
       
    }
    
    override fun onCancel(arguments: Any?) {

    }

}

在MainActivity初始化添加插件类

kotlin 复制代码
package com.example.fltest

import com.example.fltest.plugin.DeviceInfoPlugin
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine

class MainActivity: FlutterActivity(){
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        flutterEngine.plugins.add(DeviceInfoPlugin(this))
    }
}

总结:

方法 方向 使用场景
MethodChannel 双向 调用原生 API 并获取结果
EventChannel 单向(原生→Flutter) 监听持续事件(如传感器)
BasicMessageChannel 双向 简单消息传递(字符串、二进制数据)

根据具体需求选择合适的方式,可覆盖绝大多数跨平台交互场景。

相关推荐
事圆则缓6 小时前
Flutter 状态管理框架对比(二):Provider 怎样管住一份购物车
flutter
GitCode官方7 小时前
开源鸿蒙跨平台直播|Flutter HCPP 开源鸿蒙实践:让原生视图回到系统合成层
flutter·华为·harmonyos
大侠归来8 小时前
C++ 与 Lua 的协程交互:从原理到实战
c++·lua·交互
光影少年8 小时前
RN与Flutter架构区别
前端·flutter·react native·react.js·架构·node.js
m0_738185821 天前
Flutter 鸿蒙化实战:flutter_app_minimizer_plus 适配 OpenHarmony,一键最小化应用
flutter·华为·harmonyos·鸿蒙
动物园猫1 天前
Flutter 鸿蒙实战:用 webview_flutter 三方库在 鸿蒙 中内嵌真实网页
flutter·华为·harmonyos
元岳数字人小元1 天前
数字人源码系统:模块化开发赋能智能场景灵活迭代升级
运维·人工智能·开源·人机交互·交互
m0_738185821 天前
Flutter 鸿蒙化实战:flutter_app_badger 适配 OpenHarmony,应用角标
flutter·华为·harmonyos·鸿蒙
yuezhilangniao1 天前
FVM 与 Flutter 环境配置完全指南:从安装到日常使用
flutter