如何使用EventChannel获取当前时间(Flutter+Kotlin实现)
修复方案
现存问题
- 两端EventChannel名称不匹配:Flutter端定义的通道名为
samples.flutter.dev/eventChannel_profile,Kotlin端配置的通道名不一致,会导致通信完全失效 - Kotlin端未保存EventSink实例、未实现时间发送逻辑,且EventSink强制要求在主线程调用,否则Flutter端无法正常接收数据
- Flutter端未实现按钮点击触发逻辑,初始直接监听流会导致进入页面就自动请求时间,不符合点击触发的需求
Kotlin端完整代码
直接替换MainActivity中对应代码即可:
import android.util.Log import android.os.Handler import android.os.Looper import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.EventChannel class MainActivity : FlutterActivity() { private val EVENT_CHANNEL = "samples.flutter.dev/eventChannel_profile" private var eventSink: EventChannel.EventSink? = null private val mainHandler = Handler(Looper.getMainLooper()) override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENT_CHANNEL).setStreamHandler( object : EventChannel.StreamHandler { override fun onListen(arguments: Any?, events: EventChannel.EventSink) { eventSink = events // Flutter端开始监听时,直接发送当前时间戳(毫秒级) sendCurrentTime() } override fun onCancel(arguments: Any?) { Log.w("Android", "EventChannel onCancel called") eventSink = null } } ) } private fun sendCurrentTime() { val time = System.currentTimeMillis() // 切换到主线程发送事件,避免线程异常 mainHandler.post { eventSink?.success(time) } } }
Flutter端调整后代码
补全按钮点击逻辑,改为点击时才触发流监听获取时间:
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { static const EventChannel _eventPlatform = EventChannel('samples.flutter.dev/eventChannel_profile'); int? currentTime; StreamSubscription? _timeSub; void _getUpdateProfile() { _timeSub?.cancel(); // 点击时开始监听流,触发Kotlin侧onListen回调 _timeSub = _eventPlatform.receiveBroadcastStream().cast<int>().listen((ts) { setState(() { currentTime = ts; }); _timeSub?.cancel(); }); } @override void dispose() { _timeSub?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( padding: const EdgeInsets.all(20), child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text(currentTime != null ? "Current Time: $currentTime" : "Waiting for get data..."), const SizedBox(height: 30), ElevatedButton( onPressed: _getUpdateProfile, child: const Text('Get Update Profile'), ), ], ), ), ), ); } }
注意事项
- 时间数据全程仅通过EventChannel传递,无其他通道参与
- 两端通道名必须完全一致,大小写、特殊字符不能有任何偏差
- 页面销毁时必须取消流订阅,避免内存泄漏
- 若需要持续接收时间更新,可移除
_timeSub?.cancel()逻辑,Kotlin侧可使用定时器循环调用sendCurrentTime()即可
内容的提问来源于stack exchange,提问作者userName
相关产品推荐
相关产品推荐

