第三百九十九回

我们在上一章回中介绍了MethodChannel的使用方法,本章回中将介绍EventChannel的使用方法.闲话休提,让我们一起Talk Flutter吧。

在这里插入图片描述

知识回顾

我们在前面章回中介绍了通道的概念和作用,并且提到了通道有不同的类型,本章回将其中一种通道:EventChannel.该通道主要通过Stream实现通信功能,该通道
主要用于消息类通信功能,它只能通过原生平台向Flutter程序发送消息,属于单向通信,本章回中将详细介绍它的使用方法。

示例代码

通道的使用方法在前面章节已经介绍过,不过比较抽象,我们在这里通过具体的示例代码来演示:

  1. 在Flutter中创建通道,使用构造方法就可以创建通道,方法的参数最好使用域名/功能名这样的形式,因为在原生代码中会通过该名称获取该通道;
  flutterEventChannel = EventChannel("www.acf.com/event");
  1. 监听通道中的方法或者事件.这里使用通道的receiveBroadcastStream()方法监听通道中的事件,它可以获取到方法的的返回值和错误信息。它本质上是Stream
    因此它的使用方法和Stream相同,我们已经介绍过Stream,因此不做详细介绍。
    var streamSubscription = flutterEventChannel.receiveBroadcastStream()
        .listen((event) { debugPrint("data: ${event.toString()}");},
    onError: (e) => debugPrint('error: ${e.toString()}'),
    onDone: () => debugPrint('event done'),
    cancelOnError: true);
  }
  1. 在原生平台的代码中获取通道;这里继承了FlutterActivity类并且重写类中的configureFlutterEngine()方法,在该方法中获取通道;
class MainActivity: FlutterActivity() {
    private val eventChannel = "www.acf.com/event"
    //重写方法来设置chanel监听器,用来监听channel中的方法
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        //通过方法中的flutterEngine获取MethodChannel对象
        val eventChannel = EventChannel(flutterEngine.dartExecutor.binaryMessenger,eventChannel)

        // 设置监听器用来监听channel中的事件
        var sHandler = StreamHandlerImpl()
        eventChannel.setStreamHandler(sHandler)
    }
}
  1. 给通道设置监听器,在监听器中实现原生平台上特有的功能;设置监听器通过setStreamHandler()方法实现,详细可以参考上面的代码片段。该方法需要传递一个
    StreamHandler类型的对象,我们创建一个该类的子类,并且在类中重写了相关的方法,在方法给给Stream回复消息,详细如下:
class StreamHandlerImpl : EventChannel.StreamHandler {
    override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
        events?.success("native event")
    }

    override fun onCancel(arguments: Any?) {
        TODO("Not yet implemented")
    }
}

上面的代码中使用回调方法的events参数给Stream回复消息,Stream收到消息后可以获取到消息的内容。
上面步骤中的3和4是在Andoird平台上编写的,位于MainActivity.kt文件中。我们还需要在IOS平台上实现类似的代码,我在这里就不演示了,因为它们的思路相同。

经验总结

本章回中介绍了EventChannel通道相关的知识,原生平台通过Stream给Flutter发送数据。这样便实现了通信功能。我在这里就不演示程序的运行结果了,建议大家
自己动手去实现。不过我分享一些编译时的经验。

  • EventChannel通道常用来发送一些消息,它的用法和Stream类似;
  • 编写channel中的代码时需要使用xCode打开flutter的项目;
  • 编写channel中的代码时最后使用androidStudio重新打开andorid项目,这样会自动生成android项目文件,而不要在原来的flutter项目中编辑android代码。
  • 运行时IOS原生代码需要使用xCode编译运行,Android原生代码需要在flutter项目中编译运行才有效果。
    看官们,与"如何使用EventChannel"相关的内容就介绍到这里,欢迎大家在评论区交流与讨论!
<think>好的,用户问的是“DateFormat.java:399是怎么事”,我需要先弄清楚这个问题具体指的是什么。首先,DateFormat是Java中处理日期格式化的类,属于java.text包。用户提到的行号399可能是在某个特定版本的JDK源码中出现的错误或异常,比如空指针、格式不正确等。 接下来,我应该忆一下常见的DateFormat问题。比如,线程安全性问题。因为SimpleDateFormat不是线程安全的,如果在多线程环境下共享实例,可能会导致异常。不过用户提到的是DateFormat.java本身的行号,可能是在使用过程中抛出的异常,比如解析错误。 我需要检查JDK源码中DateFormat.java的第399行具体是什么内容。由于不同JDK版本源码可能不同,我得找一个典型的版本来分析。例如,在OpenJDK 8中,DateFormat的某些实现可能在第399行附近涉及格式解析或应用模式的方法。 假设用户在解析日期字符串时遇到了异常,比如ParseException,错误指向DateFormat.java的第399行。这时候常见的原因包括输入的日期字符串与格式不匹配,比如格式字符串为"yyyy-MM-dd",但输入的是"2024/03/26",或者含有非法字符。 解决方法是检查使用的模式是否与输入字符串完全匹配,包括分隔符和位数。例如,使用"yyyy-MM-dd"来解析"2024-03-26"是正确的,但解析"2024/03/26"就会失败。此外,还要注意处理可能的空值,确保传入的字符串不为null。 另外,线程安全问题也可能导致异常,但通常表现为随机错误或数据损坏,而不是特定的行号错误。不过如果用户是在多线程环境下使用非线程安全的DateFormat实例,也可能导致各种异常,包括在解析时出现意料之外的问题。 总结可能的原因后,我需要给出具体的解决步骤,比如检查日期格式、使用线程安全的替代类(如DateTimeFormatter),或者正确处理异常。同时,提供示例代码展示正确用法和常见错误情况。 最后,根据问题涉及的知识点,提出相关问题,如线程安全、替代类、ParseException处理等。</think><< `DateFormat.java:399` 通常指向 Java 日期格式化类 (`DateFormat` 或 `SimpleDateFormat`) 在解析或格式化日期时发生的异常,具体原因可能是格式与输入字符串不匹配、线程安全问题或空指针等问题。以下是常见原因和解决方法: --- ### **1. 格式与输入不匹配** **问题原因**: 当调用 `parse()` 方法时,如果输入的字符串与 `DateFormat` 的模式(如 `"yyyy-MM-dd"`)不匹配,会抛出 `ParseException`。例如: ```java SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); sdf.parse("2024/03/26"); // 错误的分隔符 "/" 而不是 "-" ``` **解决方法**: 确保输入字符串与格式完全一致: ```java SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date date = sdf.parse("2024-03-26"); // 正确格式 ``` --- ### **2. 线程安全问题** **问题原因**: `SimpleDateFormat` 是非线程安全的类。如果在多线程中共享同一个实例,可能导致 `NumberFormatException` 或数据混乱。例如: ```java // 错误示例:多线程共享同一个 SimpleDateFormat public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 多线程调用 sdf.parse(...) 可能导致异常 ``` **解决方法**: 使用线程安全的替代方案(如 `DateTimeFormatter`)或为每个线程创建独立实例: ```java // Java 8+ 的线程安全方案 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate date = LocalDate.parse("2024-03-26", formatter); ``` --- ### **3. 空指针异常** **问题原因**: 如果尝试格式化或解析 `null` 值,会抛出 `NullPointerException`: ```java SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); sdf.format(null); // 抛出 NullPointerException ``` **解决方法**: 检查输入是否为 `null`: ```java if (input != null) { sdf.format(input); } ``` --- ### **示例代码(正确用法)** ```java try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date date = sdf.parse("2024-03-26"); // 正确格式 System.out.println(date); } catch (ParseException e) { e.printStackTrace(); // 处理格式错误 } ``` --- ### **源码行号解释** 在 JDK 源码中,`DateFormat.java:399` 可能对应解析逻辑的某一行(如模式匹配失败时的异常抛出)。例如,在解析过程中检测到非法字符或格式错误时,会抛出 `ParseException`。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值