Android原生与flutter模块交互

Flutter定义了三种不同类型的Channel:
BasicMessageChannel:用于传递字符串和半结构化的信息,持续通信,收到消息后可以回复此次消息,如:Native将遍历到的文件信息陆续传递到Dart,在比如:Flutter将从服务端陆陆续获取到信息交个Native加工,Native处理完返回等;
MethodChannel:用于传递方法调用(method invocation)一次性通信:如Flutter调用Native拍照;
EventChannel: 用于数据流(event streams)的通信,持续通信,收到消息后无法回复此次消息,通过长用于Native向Dart的通信,如:手机电量变化,网络连接变化,陀螺仪,传感器等;
项目当前选择的Channel是BasicMessageChannel作为传输数据的通道。

BasicMessageChannel目前传递数据提供的几种消息类型分别是JSONMessageCodec、StandardMessageCodec、StringCodec、BinaryCodec四种类型。
当前项目选择以JSON格式进行数据传输,所以使用的消息类型是JSONMessageCodec。

JSONMessageCodec在flutter里面可传递的数据类型有5种:
分别是bool,num,String,List,Map
在这里插入图片描述
在这里插入图片描述

在项目中使用 BasicMessageChannel 通道 Flutter向Android原生接收与发送请求,Android原生向Flutter接收与发送请求则如下:

首先Flutter向Android原生交互需要先注册唯一标识,唯一标识两端必须一致,iOS原生也是一样

当前唯一标识 CHANNEL_NAME = "flutter_to_native_json_basic"

项目Flutter端代码,设置 BasicMessageChannel 消息通道的方式:

/// 指定原生端与flutter之间交互的消息通道
late BasicMessageChannel channel;

/// 初始化消息通道
initChannel(Function(String)? toPage) {
  this.toPage = toPage;
  /// 创建 Flutter端和原生端的,相互通信的通道
  channel = const BasicMessageChannel(
      KtNativeConstant.CHANNEL_NAME, JSONMessageCodec());
  // 监听来自 原生端 的消息通道,原生端调用了函数,这个handler函数就会被触发
  channel.setMessageHandler(_handler);
}

/// 监听来自 原生端 的消息通道
/// 原生端调用了函数,这个handler函数就会被触发
Future<dynamic> _handler(dynamic message) async {
  nativeBean = KtNativeBean.formJson(message);
  KtLog.e("nativeBean: key = ${nativeBean?.key}");
  /// 接受参数成功返回0给原生端
  return 0;
}

/// flutter向原生端发送消息
flutterSendNativeData(Map<String, String> map) {
  channel.send(map).then((value) {
    KtLog.d("原生端接收成功的数据 value = $value");
  }).catchError((error) {
    /// 发送消息出现错误异常情况接收回调
    if (error is MissingPluginException) {
      KtLog.e(
          "flutterSendNativeData ---- Error:notImplemented --- 未在原生端找到具体实现函数");
    } else {
      KtLog.e("flutterSendNativeData ---- Error:$error");
    }
  });
}

项目Android原生端代码,设置 BasicMessageChannel 消息通道的方式(原生项目首先需搭建与Flutter通讯的activity):
在 KtFlutterActivity 中 设置:

/**
* 原生端与Flutter交互的实例对象
*/
private var channel: KtJsonBasicMessageChannel? = null

/**
* Flutter activity专属回调,在回调中注册与 Flutter 消息传输通道
* @param flutterEngine 项目 Flutter 引擎
*/
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    // 获取消息通道,并设置 Flutter 引擎
    channel = KtJsonBasicMessageChannel.getInstance(flutterEngine.dartExecutor.binaryMessenger)
    // 原生端通过通道发送数据到 Flutter
    channel?.androidSendFlutterData(
        mutableMapOf(
            "key" to "test key",
            "customData" to hashMapOf<String, Any>(),
            "token" to "test token",
            "epid" to "test epid",
            "appId" to "test appId"
        )
    )
}

原生端项目自定义的 KtJsonBasicMessageChannel 需继承于

BasicMessageChannel.MessageHandler<Any>
class KtJsonBasicMessageChannel private constructor(messenger: BinaryMessenger) : BasicMessageChannel.MessageHandler<Any>

/**
* 项目全局的消息通道
*/
private lateinit var mChannel: BasicMessageChannel<Any>

companion object {
    /**
     * 原生View 在Flutter引擎上注册的唯一标识,在Flutter端使用时必须一样
     */
    val CHANNEL_NAME = "flutter_to_native_json_basic"


    /**
     * 单例对象
     * 使用 @Volatile 关键字确保instance字段的可见性,防止多线程环境下出现指令重排序导致的问题。
     */
    @Volatile
    private var instance: KtJsonBasicMessageChannel? = null


    /**
     * 获取单例对象
     * @param messenger
     * @return
     */
    fun getInstance(messenger: BinaryMessenger): KtJsonBasicMessageChannel {
        // 通过双重检查(Double-Checked)机制,在第一次调用getInstance()时进行加锁,确保只有一个线程能够创建实例。
        return instance ?: synchronized(this) {
            instance ?: KtJsonBasicMessageChannel(messenger).also { instance = it }
        }
    }
}

/**
* 初始化消息通道
* @param messenger
*/
private fun initChannel(messenger: BinaryMessenger) {
    // 创建 Android端和Flutter端的,相互通信的通道,通道名称,两端必须一致
    mChannel = BasicMessageChannel(messenger, CHANNEL_NAME, JSONMessageCodec.INSTANCE)
    // 监听来自 Flutter端 的消息通道,Flutter端调用了函数,这个handler函数就会被触发
    mChannel.setMessageHandler(this)
}

/**
* 监听来自 Flutter端 的消息通道
* @param message   Android端 接收到 Flutter端 发来的 数据对象
* @param reply     Android端 给 Flutter端 执行回调的接口对象
*/
override fun onMessage(message: Any?, reply: BasicMessageChannel.Reply<Any>) {
    // 回调结果对象,获取Flutter端传过来的数据
    val flutterData = KtJsonUtils.fromJson(message.toString(), HashMap::class.java)
    "flutter message = ${message?.toString() ?: ""}".loge()


    // 回调状态接口对象,返回给Flutter端
    reply.reply(message)
}

/**
* Android原生端发送消息至Flutter端
* @param data  需要发送的消息
*/
fun androidSendFlutterData(data: MutableMap<String, Any>) {
    mChannel.send(data) { reply ->
        JqzLogUtils.eTag(AppConstants.LOG_HTTP_INFO_TAG, "从flutter 返回回来的数据 reply : $reply")
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值