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

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

相关推荐
CappuccinoRose2 分钟前
Web Components 基础
前端·javascript·交互·web component·shadow dom
2501_915106321 小时前
Flutter iOS混淆打包详细教程与步骤
android·flutter·ios·小程序·uni-app·iphone·webview
lqj_本人1 小时前
Flutter 鸿蒙实战:用 wakelock_plus 三方库给阅读页加上屏幕常亮
flutter·华为·harmonyos
熊猫钓鱼>_>12 小时前
Flutter app_settings 鸿蒙适配实战:Intent 体系到 Want 的跨越
flutter·华为·harmonyos·openharmony·intent·want
里欧跑得慢14 小时前
Flutter主题与样式详解
前端·css·flutter·web
程序员老刘16 小时前
现在回头看,Dart取消宏是无比正确的决定
flutter·ai编程·dart
莫道桑榆晚hh16 小时前
Flutter 双端开发实战:一套代码搞定 iOS + Android,从开发到上架全流程
flutter
Zeaon18 小时前
别再手写筛选栏了:一个可组合的 Flutter 选择组件(5 入口 × 7 委托)
android·flutter
事圆则缓18 小时前
Flutter 快速上手
flutter
「、皓子~1 天前
海狸IM 2.1 私有化部署从零到一:中间件、微服务与 Nginx 全流程
nginx·flutter·微服务·中间件·开源软件·im·海狸im