據說你還在用工具類來判斷網絡狀態?試試這個吧,像使用EventBus同樣簡單優雅

基本操做,先舉栗子🌰

在項目中老是會有須要判斷網絡狀態的地方,咱們經常使用的方法就是抽出一個工具類,我順手就是一個栗子🌰: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();
}
複製代碼

這樣作會有什麼問題呢?

  1. 首先最直觀的,不夠優雅,代碼判斷量太多,若是你的操做是須要頻繁的監聽網絡狀態,那麼過多的if/ else確定會讓後面維護變的眼花繚亂。
  2. 以上方法只能在網絡操做以前判斷網絡狀態,若用戶在網絡正常狀況下發起操做而中間改變網絡,好比下載中途忽然丟失網絡,則此時沒法作出相應的控制。
  3. 沒法只針對某種網絡類型進行監聽,好比只想監聽用戶切換到 WiFi 網絡時作出響應。
  4. 程序多處須要進行網絡監聽處理時,不能同時接收網絡變化,必須逐個地方手動處理。

如何解決

接下來就是本文的重點,如何經過 NetStatusBus 這個庫來解決以上問題,讓你的網絡狀態監聽變得史無前例的簡單粗暴。github

經過如下方式來使用 NetStatusBus

  1. 經過 Gradle 添加依賴:
implementation 'com.sunchen:netstatusbus:0.1.4'
複製代碼
  1. Application 中初始化 NetStatusBus:
// 儘量早的進行這一步操做, 建議在 Application 中完成初始化操做
 NetStatusBus.getInstance().init(this);
複製代碼
  1. 根據你的生命週期來註冊和註銷訂閱者,例如:
@Override
 public void onStart() {
     super.onStart();
     NetStatusBus.getInstance().register(this);
 }

 @Override
 public void onStop() {
     super.onStop();
     NetStatusBus.getInstance().unregister(this);
 }
複製代碼
  1. 聲明你的訂閱方法,在該方法中能夠監聽到網絡狀態的變動:
@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 這個庫的內容,但願能夠對你有幫助,喜歡的話請不吝點贊,感謝。

相關文章
相關標籤/搜索