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 双向 简单消息传递(字符串、二进制数据)

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

相关推荐
小哥Mark1 小时前
Flutter开发鸿蒙年味 + 实用实战应用|绿色烟花:电子烟花 + 手持烟花
flutter·华为·harmonyos
一只大侠的侠3 小时前
Flutter开源鸿蒙跨平台训练营 Day 3
flutter·开源·harmonyos
一只大侠的侠4 小时前
【Harmonyos】Flutter开源鸿蒙跨平台训练营 Day 2 鸿蒙跨平台开发环境搭建与工程实践
flutter·开源·harmonyos
方见华Richard4 小时前
世毫九实验室(Shardy Lab)研究成果清单(2025版)
人工智能·经验分享·交互·原型模式·空间计算
微祎_5 小时前
Flutter for OpenHarmony:构建一个 Flutter 平衡球游戏,深入解析动画控制器、实时物理模拟与手势驱动交互
flutter·游戏·交互
爱喝白开水a5 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
ZH15455891316 小时前
Flutter for OpenHarmony Python学习助手实战:面向对象编程实战的实现
python·学习·flutter
renke33646 小时前
Flutter for OpenHarmony:构建一个 Flutter 色彩调和师游戏,RGB 空间探索、感知色差计算与视觉认知训练的工程实现
flutter·游戏
王码码20357 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
ujainu8 小时前
Flutter + OpenHarmony 实现经典打砖块游戏开发实战—— 物理反弹、碰撞检测与关卡系统
flutter·游戏·openharmony·arkanoid·breakout