【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | Android 端实现 BasicMessageChannel 通信 )
文章目錄
- 前言
- 一、Android 端 BasicMessageChannel 構(gòu)造函數(shù)
- 二、Android 端 MessageCodec 子類實現(xiàn)
- 三、Android 端 setMessageHandler 方法
- 四、Android 端 send 方法
- 五、Android 端實現(xiàn) BasicMessageChannel 通信步驟
- 六、相關(guān)資源
前言
本博客與 【Flutter】Flutter 混合開發(fā) ( Flutter 與 Native 通信 | 在 Flutter 端實現(xiàn) BasicMessageChannel 通信 ) 博客相對應(yīng) , 該博客中開發(fā) Flutter 的 Dart 端 ;
本博客中開發(fā) Android 中的 Java 端 , 最終目標(biāo)是二者可以進行信息交流 ;
一、Android 端 BasicMessageChannel 構(gòu)造函數(shù)
Android 端 Java 中 , BasicMessageChannel 構(gòu)造函數(shù)方法原型如下 :
public final class BasicMessageChannel<T> {@NonNull private final BinaryMessenger messenger;@NonNull private final String name;@NonNull private final MessageCodec<T> codec;/*** Creates a new channel associated with the specified {@link BinaryMessenger} and with the* specified name and {@link MessageCodec}.** @param messenger a {@link BinaryMessenger}.* @param name a channel name String.* @param codec a {@link MessageCodec}.*/public BasicMessageChannel(@NonNull BinaryMessenger messenger, @NonNull String name, @NonNull MessageCodec<T> codec) {if (BuildConfig.DEBUG) {if (messenger == null) {Log.e(TAG, "Parameter messenger must not be null.");}if (name == null) {Log.e(TAG, "Parameter name must not be null.");}if (codec == null) {Log.e(TAG, "Parameter codec must not be null.");}}this.messenger = messenger;this.name = name;this.codec = codec;} }BasicMessageChannel 接收 333 個參數(shù) :
- BinaryMessenger messenger : 用于 發(fā)送 / 接收消息 ;
- String name : Channel 消息通道的名稱 , 該名稱必須與 Dart 中的消息通道名稱相同 ;
- MessageCodec<T> codec : 消息編解碼器 ;
二、Android 端 MessageCodec 子類實現(xiàn)
MessageCodec 消息編解碼器的子類實現(xiàn) : 在 Android Studio 使用 Ctrl + H , 查看 MessageCodec 子類 , 有 444 個子類 ;
- BinaryCodec : 二進制編解碼器 , 返回值類型 和 入?yún)㈩愋?都是二進制格式 , 即 Byte 數(shù)組 ; 編解碼器沒有做任何操作 , 原封不動的傳遞二進制數(shù)據(jù) ; 支持 二進制數(shù)據(jù) ;
- 適用場景 : 傳遞大量的二進制數(shù)據(jù) , 如圖片 , 音視頻等 , 可以直接傳遞內(nèi)存塊 , 不用再進行編解碼 , 導(dǎo)致消耗不必要的性能 ;
- StringCodec : 二進制 Byte 數(shù)組與字符串之間進行編解碼 , 字符串編碼格式 UTF-8 ; 發(fā)送的時候是 String 類型 , 經(jīng)過 Channel 通道時編碼成二進制類型 , 接收時在解碼成 String 類型 ; 支持 字符串 數(shù)據(jù) ;
- JSONMessageCodec : 二進制數(shù)據(jù) 與 基礎(chǔ)數(shù)據(jù) 之間進行編解碼 , 支持 基礎(chǔ)數(shù)據(jù)類型 / 列表 / 字典 ;
- StandardMessageCodec : BasicMessageChannel 消息通道的 默認編碼器 ; 支持 基礎(chǔ)數(shù)據(jù)類型 / 二進制數(shù)據(jù) / 列表 / 字典
BinaryCodec 實現(xiàn) :
- Android : ByteBuffer ;
- iOS : NSData ;
- Flutter : Uint8List ;
StringCodec 實現(xiàn) :
- Android : java.lang.String ;
- iOS : NSString ;
- Flutter : String ;
JSONMessageCodec 實現(xiàn) :
- Android : SONUtil , StringCodec ;
- iOS : NSJSONSerialization ;
三、Android 端 setMessageHandler 方法
創(chuàng)建了 BasicMessageChannel 實例對象后 , 需要設(shè)置信息監(jiān)聽 , 如果要接收 Dart 端發(fā)送來的消息 , 需要設(shè)置消息處理器 ;
調(diào)用 setMessageHandler 方法 , 可以為 BasicMessageChannel 設(shè)置一個 消息處理器 ;
BasicMessageChannel.setMessageHandler 函數(shù)原型如下 :
/*** Registers a message handler on this channel for receiving messages sent from the Flutter* application.** <p>Overrides any existing handler registration for (the name of) this channel.** <p>If no handler has been registered, any incoming message on this channel will be handled* silently by sending a null reply.** @param handler a {@link MessageHandler}, or null to deregister.*/@UiThreadpublic void setMessageHandler(@Nullable final MessageHandler<T> handler) {messenger.setMessageHandler(name, handler == null ? null : new IncomingMessageHandler(handler));}設(shè)置的 MessageHandler<T> handler 參數(shù) , 就是消息處理器 ;
在 MessageHandler 接口中 , 只有一個 onMessage 方法 , 該方法是用于接收 Dart 傳遞來的消息的 ;
onMessage 參數(shù)簡介 :
- T message : Dart 端傳遞來的消息 ;
- Reply<T> reply : 向 Dart 端回傳的數(shù)據(jù) ;
MessageHandler 接口原型如下 :
/** A handler of incoming messages. */public interface MessageHandler<T> {/*** Handles the specified message received from Flutter.** <p>Handler implementations must reply to all incoming messages, by submitting a single reply* message to the given {@link Reply}. Failure to do so will result in lingering Flutter reply* handlers. The reply may be submitted asynchronously.** <p>Any uncaught exception thrown by this method, or the preceding message decoding, will be* caught by the channel implementation and logged, and a null reply message will be sent back* to Flutter.** <p>Any uncaught exception thrown during encoding a reply message submitted to the {@link* Reply} is treated similarly: the exception is logged, and a null reply is sent to Flutter.** @param message the message, possibly null.* @param reply a {@link Reply} for sending a single message reply back to Flutter.*/void onMessage(@Nullable T message, @NonNull Reply<T> reply);}四、Android 端 send 方法
BasicMessageChannel 通道向 Dart 發(fā)送數(shù)據(jù)有兩個重載的方法 ;
- void send(@Nullable T message) 方法 : 單純的向 Dart 端發(fā)送數(shù)據(jù) , 不接受返回的數(shù)據(jù) ;
- void send(@Nullable T message, @Nullable final Reply<T> callback) 方法 : 向 Dart 端發(fā)送數(shù)據(jù) , 并接收 Dart 端返回的數(shù)據(jù) ;
send 方法參數(shù)說明 :
- T message 參數(shù) : 要發(fā)送給 Dart 端的數(shù)據(jù) ;
- final Reply<T> callback 參數(shù) : 消息發(fā)送到 Dart 端后 , 如果 Dart 端返回消息 , 會觸發(fā)該回調(diào)接口 ;
send 函數(shù)原型 :
public final class BasicMessageChannel<T> {/*** Sends the specified message to the Flutter application on this channel.** @param message the message, possibly null.*/public void send(@Nullable T message) {send(message, null);}/*** Sends the specified message to the Flutter application, optionally expecting a reply.** <p>Any uncaught exception thrown by the reply callback will be caught and logged.** @param message the message, possibly null.* @param callback a {@link Reply} callback, possibly null.*/@UiThreadpublic void send(@Nullable T message, @Nullable final Reply<T> callback) {messenger.send(name,codec.encodeMessage(message),callback == null ? null : new IncomingReplyHandler(callback));} }五、Android 端實現(xiàn) BasicMessageChannel 通信步驟
Android 端實現(xiàn) BasicMessageChannel 通信步驟 :
首先 , 獲取 FlutterEngine 實例對象 , 需要從該實例對象中獲取 BinaryMessenger ; 這里從 FlutterFragment 中獲取 , 從 FlutterActivity 中也可以獲取 ;
FlutterFragment mFlutterFragment = FlutterFragment.withNewEngine().initialRoute("嵌入 FlutterFragment").build();mFlutterFragment.getFlutterEngine();然后 , 構(gòu)建 BasicMessageChannel 對象 , 傳入如下參數(shù) :
// 初始化 BasicMessageChannel mBasicMessageChannel = new BasicMessageChannel(mFlutterFragment.getFlutterEngine().getDartExecutor(),"BasicMessageChannel",StringCodec.INSTANCE);在后 , 設(shè)置消息接收監(jiān)聽 , 監(jiān)聽從 Dart 端傳遞來的消息 , 如果有消息傳來 , 會自動回調(diào) MessageHandler 中的 onMessage 方法 ;
// 設(shè)置消息接收監(jiān)聽 mBasicMessageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler<String>() {@Overridepublic void onMessage(@Nullable String message, @NonNull BasicMessageChannel.Reply reply) {show_message.setText("Dart 通過 BasicMessageChannel 通道向 Native 發(fā)送 " + message + " 信息");} });最后 , 設(shè)置發(fā)送消息 , 點擊按鈕后 , 即可向 Dart 端發(fā)送消息 , 同時設(shè)置 Reply 參數(shù) , 如果 Dart 端有回送反饋 , 則自動回調(diào) BasicMessageChannel.Reply 接口中的 void reply(@Nullable Object reply) 方法 ;
// 點擊按鈕發(fā)送消息 , 并設(shè)置 Reply 接收 Dart 返回的消息 findViewById(R.id.channel1).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mBasicMessageChannel.send("Native 通過 BasicMessageChannel 通道發(fā)送消息 Hello !",new BasicMessageChannel.Reply() {@Overridepublic void reply(@Nullable Object reply) {show_message.setText("Native 通過 BasicMessageChannel 通道發(fā)送消息 Hello 后 , Dart 反饋的信息 ");}});} });六、相關(guān)資源
參考資料 :
- Flutter 官網(wǎng) : https://flutter.dev/
- Flutter 插件下載地址 : https://pub.dev/packages
- Flutter 開發(fā)文檔 : https://flutter.cn/docs ( 強烈推薦 )
- 官方 GitHub 地址 : https://github.com/flutter
- Flutter 中文社區(qū) : https://flutter.cn/
- Flutter 實用教程 : https://flutter.cn/docs/cookbook
- Flutter CodeLab : https://codelabs.flutter-io.cn/
- Dart 中文文檔 : https://dart.cn/
- Dart 開發(fā)者官網(wǎng) : https://api.dart.dev/
- Flutter 中文網(wǎng) : https://flutterchina.club/ , http://flutter.axuer.com/docs/
- Flutter 相關(guān)問題 : https://flutterchina.club/faq/ ( 入門階段推薦看一遍 )
- GitHub 上的 Flutter 開源示例 : https://download.csdn.net/download/han1202012/15989510
- Flutter 實戰(zhàn)電子書 : https://book.flutterchina.club/chapter1/
- Dart 語言練習(xí)網(wǎng)站 : https://dartpad.dartlang.org/
重要的專題 :
- Flutter 動畫參考文檔 : https://flutterchina.club/animations/
博客源碼下載 :
-
GitHub 地址 : ( 隨博客進度一直更新 , 有可能沒有本博客的源碼 )
- Flutter Module 工程 : https://github.com/han1202012/flutter_module
- Android 應(yīng)用 : https://github.com/han1202012/flutter_native
- 注意 : 上面兩個工程要放在同一個目錄中 , 否則編譯不通過 ;
-
博客源碼快照 : https://download.csdn.net/download/han1202012/21670919 ( 本篇博客的源碼快照 , 可以找到本博客的源碼 )
總結(jié)
以上是生活随笔為你收集整理的【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | Android 端实现 BasicMessageChannel 通信 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【错误记录】Flutter 混合开发获取
- 下一篇: 【错误记录】Flutter 混合开发报错