在項目中老是會有須要判斷網絡狀態的地方,咱們經常使用的方法就是抽出一個工具類,我順手就是一個栗子🌰:java
//判斷網絡是否可用
public static boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager)
getApplication()
.getSystemService(Context.CONNECTIVITY_SERVICE);
...
...
return boolean;
}
複製代碼
細緻的你固然還會再寫一個判斷網絡類型的方法,反手再來一個栗子🌰:android
//返回當前網絡類型
public static NetType getNetType() {
ConnectivityManager connectivityManager = (ConnectivityManager)
getApplication()
.getSystemService(Context.CONNECTIVITY_SERVICE);
...
...
return NetType;
}
複製代碼
而後咱們就會在相應的操做前進行判斷網絡的判斷:git
if (NetworkUtils.isNetworkAvailable()) {
doSomething();
} else {
doSomething();
}
if (NetworkUtils.getNetType()== xxx) {
doSomething();
} else {
doSomething();
}
複製代碼
if
/ else
確定會讓後面維護變的眼花繚亂。接下來就是本文的重點,如何經過 NetStatusBus 這個庫來解決以上問題,讓你的網絡狀態監聽變得史無前例的簡單粗暴。github
implementation 'com.sunchen:netstatusbus:0.1.4'
複製代碼
// 儘量早的進行這一步操做, 建議在 Application 中完成初始化操做
NetStatusBus.getInstance().init(this);
複製代碼
@Override
public void onStart() {
super.onStart();
NetStatusBus.getInstance().register(this);
}
@Override
public void onStop() {
super.onStop();
NetStatusBus.getInstance().unregister(this);
}
複製代碼
@NetSubscribe()
public void doSometing(NetType netType) {
//netType 會返回當前的網絡類型爲 NetType.WIFI 仍是 NetType.MOBILE 或者NetType.NONE
Log.d(Constrants.LOG_TAG, netType.name());
}
複製代碼
到這裏就已經結束了,你的全部網絡操做已經均可以清晰優雅的在訂閱方法中進行處理了,固然你也能夠繼續往下看。api
訂閱方法能夠選填一個NetType
參數,能夠經過NetType
的值來判斷當前網絡類型。安全
@NetSubscribe
中能夠指定 mode
用來設置訂閱的模式,mode
類型以下:網絡
Mode.AUTO
:這是默認值,任何網絡狀態發生變化,該類型訂閱者都會被調用。ide
//全部網絡變化都會被調用,能夠經過 NetType 來判斷當前網絡具體狀態
@NetSubscribe(mode = Mode.AUTO)
public void netChange(NetType netType) {
Log.d(Constrants.LOG_TAG, netType.name());
}
複製代碼
Mode.WIFI
:由 WIFI 改變引起的網絡狀態變化的狀況下(wifi鏈接和斷開),該類型訂閱者會被調用。工具
// 當 wifi 鏈接和失去鏈接時都被調用
@NetSubscribe(mode = Mode.WIFI)
public void wifiChange(NetType netType) {
Log.d(Constrants.LOG_TAG, netType.name());
}
複製代碼
Mode.WIFI_CONNECT
: 僅在 WIFI 成功鏈接後,該類型訂閱者會被調用。性能
// 只有當 wifi 鏈接時都被調用
@NetSubscribe(mode = Mode.WIFI_CONNECT)
public void wifiChange() {
Log.d(Constrants.LOG_TAG, "鏈接到wifi網絡");
}
複製代碼
Mode.MOBILE
: 由移動網絡改變引起的網絡狀態變化的狀況時(移動網絡鏈接和斷開),該類型訂閱者會被回調。
// 當移動網絡鏈接和失去鏈接時都會被調用
@NetSubscribe(mode = Mode.MOBILE)
public void netChange(NetType netType) {
Log.d(Constrants.LOG_TAG, netType.name());
}
複製代碼
Mode.MOBILE _CONNECT
: 僅在移動網絡成功鏈接後,會被回調。
// 當移動網絡鏈接時調用
@NetSubscribe(mode = Mode.MOBILE _CONNECT)
public void netChange() {
Log.d(Constrants.LOG_TAG, "鏈接到移動網絡");
}
複製代碼
Mode.NONE
: 只有當網絡丟失時,該類型訂閱者纔會被回調。
// 只有當網絡丟失時,該類型訂閱者纔會被回調。
@NetSubscribe(mode = Mode.NONE)
public void netChange() {
Log.d(Constrants.LOG_TAG, "失去網絡");
}
複製代碼
有人會以爲,我用個庫爽就好了管它的原理幹什麼?
你放心,我只是小小的描述一下實現方式。
原理簡單來講,就是在全局初始化的時候就綁定對網絡的變化監聽。而後將進行註冊的父類全部的訂閱方法保存至集合中,這裏涉及到一些方法的校驗,最後在網絡狀態發生改變時利用 Java 反射機制遍歷執行全部訂閱方法。熟悉 EventBus 的小夥伴已經看出來了這裏借鑑了一小部分 EventBus 的思想。
回到第一步,那麼具體是如何綁定對網絡狀態變化的監聽呢?
之前咱們是經過註冊廣播來實現綁定網絡變動的監聽,在Android 7.0 之後,Google 基於性能和安全緣由對廣播進行了不少限制,好比監聽網絡變動的廣播 android.net.conn.CONNECTIVITY_CHANGE
使用靜態註冊的方式則沒法生效,而動態註冊的方式雖然能夠生效但畢竟不是最優解。
一樣出於性能和安全,以及擁抱變化的角度,最終咱們仍是使用官方推薦的方式,利用 ConnectivityManager.NetworkCallback 來進行網絡變化的監聽,這是在Android 5.0即android api 21推出的API,目前Android 5.0以上的市場佔有率在 85%以上,隨着國內各大廠商正在積極的推動適配普及Android Q,這個比例還會進一步增大,因此我的人認爲無需過於擔憂低版本適配。
好的,這就關於 NetStatusBus 這個庫的內容,但願能夠對你有幫助,喜歡的話請不吝點贊,感謝。