- MethodChannel(方法通道)
用途:實現 雙向通信,用于調用原生平臺提供的 API 并獲取返回結果。
場景:適合一次性操作,如調用相機、獲取設備信息等。
使用步驟:
- Flutter 端:通過 MethodChannel監聽事件流。
static const platform =MethodChannel('com.example.fltest.plugin.DeviceInfoPlugin');
- Android 端(Kotlin)
private var methodChannel: MethodChannel? = nullval CHANNEL: String = "com.example.fltest.plugin.DeviceInfoPlugin"private fun getPhoneNumber(): Any? {val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager?
// val phoneNumber = telephonyManager!!.line1Numberval phoneNumber = "18627000332"return phoneNumber}
- EventChannel(事件通道)
用途:實現 單向數據流,用于原生平臺向 Flutter 持續發送事件(如傳感器數據)。
場景:適合實時數據流,如監聽陀螺儀、GPS 位置更新等。
使用步驟:
- Flutter 端:通過 EventChannel 監聽事件流。
static const eventChannel =EventChannel('com.example.fltest.plugin.DeviceInfoPlugin/event');Stream<int> get _batteryLevelStream {return eventChannel.receiveBroadcastStream("111").cast<int>();}
- Android 端(Kotlin)
class DeviceInfoPlugin(var context: Context) : EventChannel.StreamHandler, FlutterPlugin {private var eventChannel: EventChannel? = nullval 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 = contexteventChannel = 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 = -1if (batteryLevel != -1) {events.success(batteryLevel)} else {events.error("UNAVAILABLE", "Battery level not available.", null);}}
}
- BasicMessageChannel(基礎消息通道)
用途:支持 異步消息傳遞,使用自定義編解碼器傳遞數據。
場景:適合簡單的數據交換(如 JSON、二進制數據)。
使用步驟:
- Flutter 端:通過 BasicMessageChannel監聽事件流。
final BasicMessageChannel<String> messageChannel =BasicMessageChannel<String>('com.example.fltest.plugin.DeviceInfoPlugin/basicMessage',StringCodec(),);// 發送消息
Future<String> sendMessage(String message) async {return await messageChannel.send(message);
}void initState() {super.initState();// 設置消息處理器messageChannel.setMessageHandler((String? message) async {print('Received message from native: $message');return '$message';});}
- Android 端(Kotlin)
package com.example.fltest.pluginimport 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.StringCodecclass DeviceInfoPlugin(var context: Context) : FlutterPlugin {private var basicMessageChannel: BasicMessageChannel<String>? = nullval 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 = contextbasicMessageChannel = 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初始化添加插件類
package com.example.fltestimport com.example.fltest.plugin.DeviceInfoPlugin
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngineclass MainActivity: FlutterActivity(){override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)flutterEngine.plugins.add(DeviceInfoPlugin(this))}
}
總結:
方法 | 方向 | 使用場景 |
---|---|---|
MethodChannel | 雙向 | 調用原生 API 并獲取結果 |
EventChannel | 單向(原生→Flutter) | 監聽持續事件(如傳感器) |
BasicMessageChannel | 雙向 | 簡單消息傳遞(字符串、二進制數據) |
根據具體需求選擇合適的方式,可覆蓋絕大多數跨平臺交互場景。