Flutter插件开发 网络监听组件
现在新技术层出不穷,如果每次出新的技术,我们都深入的研究的话,很容易分散精力。新的技术可能很久之后我们才会在工作中用得上,当学的新技术无法学以致用,很容易被我们遗忘,到最后真的需要使用的时候,又要从头来过(虽然上手会更快)。我觉得身为技术人,针对新技术应该是持拥抱态度的,入了这一行你就应该知道这是一个活到老学到老的行业,所以面对新技术,不要抵触,拥抱变化就好了。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);
}
}
总结
现在新技术层出不穷,如果每次出新的技术,我们都深入的研究的话,很容易分散精力。新的技术可能很久之后我们才会在工作中用得上,当学的新技术无法学以致用,很容易被我们遗忘,到最后真的需要使用的时候,又要从头来过(虽然上手会更快)。
我觉得身为技术人,针对新技术应该是持拥抱态度的,入了这一行你就应该知道这是一个活到老学到老的行业,所以面对新技术,不要抵触,拥抱变化就好了。
Flutter 明显是一种全新的技术,而对于这个新技术在发布之初,花一个月的时间学习它,成本确实过高。但是周末花一天时间体验一下它的开发流程,了解一下它的优缺点、能干什么或者不能干什么。这个时间,并不是我们不能接受的。
如果有时间,其实通读一遍 Flutter 的文档,是最全面的一次对 Flutter 的了解过程。但是如果我们只有 8 小时的时间,我希望能关注一些最值得关注的点。
附
Android学习PDF+架构视频+面试文档+源码笔记赶紧扫描下方二维码免费领取吧
(跨平台开发(Flutter)、java基础与原理,自定义view、NDK、架构设计、性能优化、完整商业项目开发等)
更多推荐
所有评论(0)