• Flutter入门-与原生数据传递


    为了实现Flutter与原生之间的数据传递,Flutter部分通过平台通道(platform channel)将消息发送到其应用程序的所在的宿主(iOS或Android)。宿主监听的平台通道,并接收该消息。

    Flutter定义了三种不同类型的Channel:
    BasicMessageChannel:用于传递字符串和半结构化信息,持续通信,收到消息后可以回复
    MethodChannel:用于传递方法调用(method invocation),一次性通信
    EventChannel:用于数据流(event streams)通信,持续通信,收到消息后无法回复。

    这三种类型的Channel都是全双工通信,即Dart端可以主动发送消息给platform端;同样,platform端也可以主动发送消息给Dart端

    一、BasicMessageChannel用法

    1、Dart端到Native端

    Dart端代码:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class MyBasicMessageChannel extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          routes: <String, WidgetBuilder>{
            'home': (BuildContext context) => BasicMessageChannelHome(),
            'second': (BuildContext context) => BasicMessageChannelSecond()
          },
          home: BasicMessageChannelHome (),
        );
      }
    }
    
    
    class BasicMessageChannelHome extends StatefulWidget {
      
      State<BasicMessageChannelHome> createState() =>
          BasicMessageChannelHomeState();
    }
    
    class BasicMessageChannelHomeState extends State<BasicMessageChannelHome> {
      var _basicMessage = BasicMessageChannel("BasicChannel", StringCodec());
    
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: GestureDetector(
                child: Text('发送BasicMessageChannel'),
                onTap: () {
                  _basicMessage.send('JumpNativeActivity').then((value) {
                    print(value);
                  });
                },
              ),
            ),
          ),
        );
      }
    
      
      void initState() {
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          _basicMessage.setMessageHandler((message) async {
            print(message);
            return 'ACK FROM ART';
          });
        });
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    Native端代码

    package com.example.flutter_hello
    
    import android.content.Context
    import android.os.Bundle
    import android.util.Log
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.plugin.common.BasicMessageChannel
    import io.flutter.plugin.common.StringCodec
    
    const val TAG:String="MainActivity"
    
    class MainActivity : FlutterActivity() {
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            var channel = BasicMessageChannel(
                flutterEngine.dartExecutor.binaryMessenger,
                "BasicChannel",
                StringCodec.INSTANCE
            )
            channel.setMessageHandler { message, reply ->
                android.util.Log.e(TAG,message)
                reply.reply("成功跳转")
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    二、MethodChannel用法

    Dart端代码

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class FlutterMethodChannel extends StatelessWidget {
      MethodChannel methodChannel = MethodChannel('nativeCall');
    
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: GestureDetector(
              onTap: () {
                _callNativeMethod();
              },
              child: Center(
                child: Text('调用Native方法'),
              ),
            ),
          ),
        );
      }
    
      void _callNativeMethod() async {
        try {
          methodChannel.invokeMethod('nativeMethod');
        } catch (e) {
          print(e);
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    Native端代码

    package com.example.flutter_hello
    
    import android.content.Context
    import android.util.Log
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.MethodChannel
    import io.flutter.plugin.common.StringCodec
    
    var INIT_PARAMS = "initParams"
    const val TAG:String="MainActivity"
    
    class MainActivity : FlutterActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            Log.e(TAG,"onCreate")
            MethodChannel(
                flutterEngine!!.dartExecutor.binaryMessenger,
                "nativeCall"
            ).setMethodCallHandler { call, result ->
                run {
                    if (call.method.equals("nativeMethod")) {
                        result.success("success")
                        Log.e(TAG, "Get Dart call method")
                    }
                }
            }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    三、EventChannel用法

    该示例是Native端实时把网络连接状态发送给Dart端

    Dart端代码

    
    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class FlutterEventChannel extends StatefulWidget{
      
      State<FlutterEventChannel> createState() => _FlutterEventChannelState();
    }
    
    class _FlutterEventChannelState extends State<FlutterEventChannel> {
      EventChannel eventChannel=EventChannel('getNetworkState');
      String networkState="";
    
      StreamSubscription? subscription;
      
      void initState() {
        super.initState();
        subscription=eventChannel.receiveBroadcastStream().listen((event) {
          _handleEvent(event);
        });
      }
    
      
      void dispose() {
        super.dispose();
        subscription!.cancel();
      }
    
      
      Widget build(BuildContext context) {
         return MaterialApp(
           home: Scaffold(
             body: Center(
               child: Text('使用EventChannel:${networkState}'),
             ),
           ),
         );
      }
    
      void _handleEvent(int event) {
        setState(() {
          if(event==0){
            networkState="网络断开";
          }else{
            networkState="网络连接";
          }
        });
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    Native端

    采用单例模式,保存EventSink用来发送数据

    package com.example.flutter_hello
    
    import io.flutter.plugin.common.EventChannel
    
    class GloableEventChannel {
        var eventSink: EventChannel.EventSink? = null
    
        private object Holder{
            val instance=GloableEventChannel()
        }
    
        companion object{
            fun getInstance()=Holder.instance
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    网络广播接收者

    package com.example.flutter_hello
    
    import android.content.BroadcastReceiver
    import android.content.Context
    import android.content.Intent
    import android.net.ConnectivityManager
    import android.os.Build
    import android.widget.Toast
    import androidx.annotation.Nullable
    import io.flutter.plugin.common.EventChannel
    
    class NetWorkStateReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            //检测API是不是小于21,因为到了API21之后getNetworkInfo(int networkType)方法被弃用
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                //获得ConnectivityManager对象
                val connMgr =
                    context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                //获取ConnectivityManager对象对应的NetworkInfo对象
                //获取WIFI连接的信息
                val wifiNetworkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
                //获取移动数据连接的信息
                val dataNetworkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
                if (GloableEventChannel.getInstance().eventSink==null){
                    return
                }
                if (wifiNetworkInfo!!.isConnected && dataNetworkInfo!!.isConnected) {
                    GloableEventChannel.getInstance().eventSink!!.success(1)
                } else if (wifiNetworkInfo!!.isConnected && !dataNetworkInfo!!.isConnected) {
                    GloableEventChannel.getInstance().eventSink!!.success(0)
                } else if (!wifiNetworkInfo!!.isConnected && dataNetworkInfo!!.isConnected) {
                    GloableEventChannel.getInstance().eventSink!!.success(1)
                } else {
                    GloableEventChannel.getInstance().eventSink!!.success(0)
                }
            } else {
                //获得ConnectivityManager对象
                val connMgr =
                    context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                var connectedState = false
                //获取所有网络连接的信息
                val networks = connMgr.allNetworks
                //通过循环将网络信息逐个取出来
                for (i in networks.indices) {
                    //获取ConnectivityManager对象对应的NetworkInfo对象
                    val networkInfo = connMgr.getNetworkInfo(networks[i])
                    if (networkInfo!!.isAvailable && networkInfo!!.isConnected) {
                        connectedState = true
                        break
                    }
                }
                if (GloableEventChannel.getInstance().eventSink==null){
                    return
                }
                GloableEventChannel.getInstance().eventSink!!.success(if (connectedState) 1 else 0)
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    注册网络状态广播

    package com.example.flutter_hello
    
    import android.content.Context
    import android.content.Intent
    import android.content.IntentFilter
    import android.net.ConnectivityManager
    import android.os.Bundle
    import android.util.Log
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.EventChannel
    import io.flutter.plugin.common.StringCodec
    
    const val TAG:String="MainActivity"
    
    class MainActivity : FlutterActivity() {
        private lateinit var eventChannel:EventChannel
        private lateinit var networkIntentFilter:IntentFilter
        private val netWorkStateReceiver=NetWorkStateReceiver()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            Log.e(TAG,"onCreate")
            networkIntentFilter=IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
            registerReceiver(netWorkStateReceiver,networkIntentFilter)
            eventChannel= EventChannel(flutterEngine!!.dartExecutor.binaryMessenger,"getNetworkState")
            eventChannel.setStreamHandler(object : EventChannel.StreamHandler {
                override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                    if (events != null) {
                        GloableEventChannel.getInstance().eventSink=events
                    }
                }
    
                override fun onCancel(arguments: Any?) {
    
                }
    
            })
        }
        override fun onDestroy() {
            super.onDestroy()
            Log.e(TAG,"onDestroy")
            unregisterReceiver(netWorkStateReceiver)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 相关阅读:
    深度学习基础 - 牛顿法
    SAP ABAP 主动调用外部系统的REST接口(x-www-form-urlencoded)
    C++完全背包
    linux运维笔记:TCP/IP三次握手和四次挥手
    界面控件Telerik UI for WPF - 如何使用RadSpreadsheet记录或评论
    生产制造管理系统对中小型企业的作用有哪些?
    非常详细的Maven安装与配置教程
    java基于Springboot+vue的文体文具销售商城网站 elementui
    简单理解prototype原型对象、原型链
    Vue3.x的设计理念-Vue3导读
  • 原文地址:https://blog.csdn.net/u011557841/article/details/127680801