网络状态变化监听在项目实践中常常使用到,而且可能贯穿整个项目。下面我们来介绍下它的实现方法。
它的实现原理很简单,首先注册一个BroadcastReceiver,接收到ConnectivityManager.CONNECTIVITY_ACTION事件,再获取一下当前的网络状态,即可完成监听。
普通写法:
在需要监听的类里定义一个内部类,继承BroadcastReceiver:
public class NetChangeBroadCastReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
NetworkStatus status =NetUtil.getNetWorkState(context);
//TODO 1 这里可以根据得到的网络状态进行业务处理
}
}
}
getNetWorkState方法定义在一个工具类里:
public class NetUtil {
public static NetworkStatus getNetWorkState(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
if (networkInfo.getType() == (ConnectivityManager.TYPE_WIFI)) {
return NetworkStatus.NETWORK_WIFI;
} else if (networkInfo.getType() == (ConnectivityManager.TYPE_MOBILE)) {
return NetworkStatus.NETWORK_MOBILE;
}
}
return NetworkStatus.NETWORK_NONE;
}
}
NetworkStatus是一个枚举类型,定义几种网络状态:
public enum NetworkStatus {
NETWORK_NONE, NETWORK_MOBILE, NETWORK_WIFI
}
在Activity,Fragment或其他地方注册这个BroadcastReceiver:
netChangeReciver = new NetChangeBroadCastReciver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
application.registerReceiver(netChangeReciver, intentFilter);
这样我们已经完成了对网络状态的监听,但每次都需要在监听的地方定义一个BroadcastReceiver并注册,是不是很麻烦?代码也显得很臃肿。可以将这些代码移到BaseActivity,BaseFragment中,并定义一个空方法,在上面的TODO 1处使用,而需要监听的Activity与Fragment则继承该方法,做相应处理,这就是多态。
然而即使这样,也还不是很简洁,下面介绍一种进阶写法。
进阶写法:
如果项目多处需要监听网络状态,可以考虑在Application处注册BroadcastReceiver,为了方面管理,定义一个单例NetStatusWatch,将注册方法添加到这个类里。
BroadcastReceiver类里,添加一个接口:
public interface OnNetChangedListener {
void onNetChanged(NetworkStatus currNetStatus);
}
这个接口在NetStatusWatch里注册,一旦接收到ConnectivityManager.CONNECTIVITY_ACTION,BroadcastReceiver就通过onNetChanged方法回调给NetStatusWatch。
NetStatusWatch中也定义了一个接口:
public interface OnNetStatusChangedListener {
void onNetStatusChanged(NetworkStatus currNetStatus);
}
在需要监听网络的的地方注册这个接口,而NetStatusWatch保存了所有已注册的接口在一个List中,一旦onNetChanged回调回来网络状态,NetStatusWatch就回调网络状态给所以已注册的类。
public void regisiterListener(OnNetStatusChangedListener listener) {
if (listener == null || arrNetStatusListenr.contains(listener)) {
return;
}
arrNetStatusListenr.add(listener);
}
public void unRegisiterListener(OnNetStatusChangedListener listener) {
if (listener == null) {
return;
}
for (OnNetStatusChangedListener o : arrNetStatusListenr) {
if (o.equals(listener)) {
arrNetStatusListenr.remove(listener);
break;
}
}
}
调用的类结束使用的时候需要反注册,以释放内存。
这样在需要监听网络的地方只要regisiterListener、unRegisiterListener即可到处使用。
其他写法:
可能觉得定义接口也不够简洁,如果项目用到了EventBus、otto、RxBus的,可以考虑用它们直接发送接收网络变化的消息。
源码请点击这里,查找有关网络监听的部分。