Flutter最详细原生交互MethodChannelEventChannelBasicMessageChannel使用教程
目录
Flutter——最详细原生交互(MethodChannel、EventChannel、BasicMessageChannel)使用教程
MethodChannel(方法通道)
用途:实现 双向通信,用于调用原生平台提供的 API 并获取返回结果。
场景:适合一次性操作,如调用相机、获取设备信息等。
使用步骤:
- Flutter 端:通过 MethodChannel监听事件流。
static const platform =
MethodChannel('com.example.fltest.plugin.DeviceInfoPlugin');
- Android 端(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
}
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? = 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);
}
}
}
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);
}
@override
void initState() {
super.initState();
// 设置消息处理器
messageChannel.setMessageHandler((String? message) async {
print('Received message from native: $message');
return '$message';
});
}
- Android 端(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初始化添加插件类
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 | 双向 | 简单消息传递(字符串、二进制数据) |
根据具体需求选择合适的方式,可覆盖绝大多数跨平台交互场景。