[Flutter插件开发] 网络状态监听组件

Posted 小陈乱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Flutter插件开发] 网络状态监听组件相关的知识,希望对你有一定的参考价值。

前言

本文讲述如何开发一个Flutter插件,用于监听手机网络状态的改变。需要注意的是,此插件目前只支持安卓平台。

使用

每当网络状态改变时,NetworkListener的builder方法都会被调用,通过status回调网络状态。

NetworkListener(
  builder: (_,status)
    var networkStatuds = "";
    if (status == ConnectivityResult.none) 
      networkStatuds = "网络不可用";
    
    if (status == ConnectivityResult.has) 
      networkStatuds = "网络可用";
    
    return  Text(networkStatuds);
  ,
) 

效果

原理

使用StreamBuilder

NetworkListener内部封装了一个StreamBuilder,接收native端返回的Stream,便可回调网络状态。代码如下:

class NetworkListener extends StatelessWidget 
  const NetworkListener(
    required this.builder,
    Key? key) : super(key: key);

  final  Widget Function(BuildContext context, ConnectivityResult connectivityResult) builder;

  @override
  Widget build(BuildContext context) 
    return StreamBuilder(
      stream: NetworkStatusNotifier.getNetworkStatus(),
      builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) 
        if(snapshot.connectionState == ConnectionState.active && snapshot.hasData)
         return builder(context,snapshot.data);
        

        return builder(context,ConnectivityResult.none);
      ,
    );
  
 

如何让native端返回Stream

如何让native端返回的Strea呢?首先,需要在native端FlutterPlugin的 onAttachedToEngine中创建一个EventChannel,通过其setStreamHandler方法设置好回调什么内容给dart端。代码如下,注意network_status_notifier_ec,其需要与dart端对应。

// ...
private EventChannel eventChannel;

public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) 
  eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),"network_status_notifier_ec");
  ConnectivityBroadcastReceiver connectivityBroadcastReceiver = new ConnectivityBroadcastReceiver(flutterPluginBinding.getApplicationContext());
  eventChannel.setStreamHandler(connectivityBroadcastReceiver);


// ... 

在dart端,同样创建一个EventChannel,用于接收native返回的stream

/// Connection status check result.
enum ConnectivityResult 
  /// has network.
  has,
  /// None: Device not connected to any network
  none


class NetworkStatusNotifier 

  static const EventChannel _eventChannel = EventChannel("network_status_notifier_ec");

  static Stream<ConnectivityResult>? _networkStatus;

  static Stream<ConnectivityResult> getNetworkStatus()
    _networkStatus ??= _eventChannel.receiveBroadcastStream().map((satues) => parseResult(satues));
    return _networkStatus!;
  

  static ConnectivityResult parseResult(int i)
    switch(i)
      case 0:
        return ConnectivityResult.none;
      case 1:
        return ConnectivityResult.has;
      default:
        return ConnectivityResult.none;
    
  
 

如何监听网络

监听网络在不同的安卓版本有不同的实现,此项目在安卓N以下采用监听广播的方式监听网络状态,而大于安卓N则采用注册回调的方式。代码如下:

 public class ConnectivityBroadcastReceiver  extends BroadcastReceiver
        implements EventChannel.StreamHandler

    public ConnectivityBroadcastReceiver(Context context) 
        this.context = context;
        connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    

    private Context context;
    private ConnectivityManager connectivityManager;
    // 回调结果
    private EventChannel.EventSink events;
    public static final String CONNECTIVITY_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";
    private Handler mainHandler = new Handler(Looper.getMainLooper());
    private ConnectivityManager.NetworkCallback networkCallback;

    @Override
    public void onReceive(Context context, Intent intent) 
        if(android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            //
            if (networkInfo != null && networkInfo.isAvailable()) 
                // network is available.
                callbackNetworkStatus(1);
             else 
                // network is unavailable.
                callbackNetworkStatus(0);
            
        
    

    @Override
    public void onListen(Object arguments, EventChannel.EventSink events) 
        this.events = events;

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
            networkCallback =
                    new ConnectivityManager.NetworkCallback() 
                        @Override
                        public void onAvailable(Network network) 
                            sendEvent(1);
                        

                        @Override
                        public void onUnavailable() 
                            sendEvent(0);
                        

                        @Override
                        public void onLost(Network network) 
                            sendEvent(0);
                        
                    ;
            connectivityManager.registerDefaultNetworkCallback(networkCallback);
         else 
            context.registerReceiver(this, new IntentFilter(CONNECTIVITY_CHANGE));
        
    

    @Override
    public void onCancel(Object arguments) 
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
            if (networkCallback != null) 
                connectivityManager.unregisterNetworkCallback(networkCallback);
            
         else 
            context.unregisterReceiver(this);
        
    

    private void callbackNetworkStatus(int status)
        if(events != null)
            events.success(status);
        
    

    private void sendEvent(final int status) 
        Runnable runnable =
                new Runnable() 
                    @Override
                    public void run() 
                        events.success(status);
                    
                ;
        mainHandler.post(runnable);
    
 

文末

我总结了一些Android核心知识点,以及一些最新的大厂面试题、知识脑图和视频资料解析。

需要的直接点击文末小卡片可以领取哦我免费分享给你,以后的路也希望我们能一起走下去。(谢谢大家一直以来的支持,需要的自己领取)

Android学习PDF+架构视频+面试文档+源码笔记

部分资料一览:

  • 330页PDF Android学习核心笔记(内含8大板块)

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

  • Android BAT大厂面试题(有解析)

领取地址:

以上是关于[Flutter插件开发] 网络状态监听组件的主要内容,如果未能解决你的问题,请参考以下文章

Flutter-手机网络状态监听

flutter监听app进入前后台状态

flutter监听app进入前后台状态

flutter生命周期

如何监听状态属性变化 Flutter bloc 模式

Flutter之 flutter_after_layout组件的作用:监听页面渲染的第一帧