实现Android网络状态变化监听

网络状态变化监听在项目实践中常常使用到,而且可能贯穿整个项目。下面我们来介绍下它的实现方法。

它的实现原理很简单,首先注册一个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的,可以考虑用它们直接发送接收网络变化的消息。

源码请点击这里查找有关网络监听的部分。

你可能感兴趣的:(Android)