Android 5.0 以上監聽網絡變化


大家好,大概有一個多月沒有更新博客了,我是干什么去了呢?很明顯,程序員當然要加班……這一次跟大家分享一下新項目的一些心得。

監聽網絡變化在開發中是經常用到的,例如我們斷網有一些友好的提示,或者根據不同的網絡更改一些加載策略,例如wifi看視頻,非wifi則會有一個提示,還有極個別更惡心的偷摸的在后台給你下各種安裝包,是誰我就不一一列舉了。

在5.0以前,我們都是廣播BroadcastReceiver,注冊跟網絡變化相關的廣播,然后判斷是連接還是斷開,這種做法非常方便,但是隨着安卓的版本迭代,在權限上越來越謹慎,廣播的方式就顯得不太優雅。

打個比方,之前就是拿個大喇叭,在大街上各種喊,就好像逛地攤,各種商品的吆喝聲混在一起,需要你自己去分辨哪些是你想要的信息,而且又顯得很不安全,萬一賣的商品比較隱私呢,大家都是很低調的人。

所以在安卓5.0以上終於對網絡的監聽進行了優化,那就是通過Callback回調的方式,這種開發模式是不是很常用?例如監聽下載進度,我只需要三個回調:下載成功,下載失敗,下載的進度變化,這種回調方式針對性強,耦合性低,非常方便,和廣播相比,就好像我們是一個訂購了服務,需要的東西自動上門,very good。

廢話鋪墊了這么多,下面就是一個實戰demo。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            // 請注意這里會有一個版本適配bug,所以請在這里添加非空判斷
            if (connectivityManager != null) {
                connectivityManager.requestNetwork(new NetworkRequest.Builder().build(), new ConnectivityManager.NetworkCallback() {

                    /**
                     * 網絡可用的回調
                     * */
                    @Override
                    public void onAvailable(Network network) {
                        super.onAvailable(network);
                        Log.e("lzp", "onAvailable");
                    }

                    /**
                     * 網絡丟失的回調
                     * */
                    @Override
                    public void onLost(Network network) {
                        super.onLost(network);
                        Log.e("lzp", "onLost");
                    }

                    /**
                     * 當建立網絡連接時,回調連接的屬性
                     * */
                    @Override
                    public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
                        super.onLinkPropertiesChanged(network, linkProperties);
                        Log.e("lzp", "onLinkPropertiesChanged");
                    }

                    /**
                     *  按照官方的字面意思是,當我們的網絡的某個能力發生了變化回調,那么也就是說可能會回調多次
                     *
                     *  之后在仔細的研究
                     * */
                    @Override
                    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
                        super.onCapabilitiesChanged(network, networkCapabilities);
                        Log.e("lzp", "onCapabilitiesChanged");
                    }

                    /**
                     * 在網絡失去連接的時候回調,但是如果是一個生硬的斷開,他可能不回調
                     * */
                    @Override
                    public void onLosing(Network network, int maxMsToLive) {
                        super.onLosing(network, maxMsToLive);
                        Log.e("lzp", "onLosing");
                    }

                    /**
                     * 按照官方注釋的解釋,是指如果在超時時間內都沒有找到可用的網絡時進行回調
                     * */
                    @Override
                    public void onUnavailable() {
                        super.onUnavailable();
                        Log.e("lzp", "onUnavailable");
                    }

                });
            }
        }
    }
}

這就是今天的全部代碼了,上面已經有了響應的注釋,但是還是不夠便於我們理解,接下來就仔細的研究一下:

1、首先我們打開app,此時網絡是連接的狀態:

一打開demo,我們立刻就得到了onAvailable的回調,意思就是網絡目前可用,這一點比廣播強多了,因為我們已啟動還要單獨處理一次,而通過回調的方式,可以立刻得到當前的狀態。

2、然后我們手動關閉網絡:

哎?沒有onLosing的回調,只看到了onLost,說明我們手動關閉網絡連接是一個很粗暴的行為,就像官方注釋上寫的,如果是一個生硬的斷開,他可能不回調。

3、最后我們再次連接網絡:

這次的回調就比較多了,首先是onAvailable,顯示網絡可用,然后是onCapabilitiesChanged,說此時網絡的連接能力發生了第一次變化,估計是連接中把,再然后是onLinkPropertiesChanged,說明連接的屬性已經發生了變化,此時應該獲得了ip地址等信息,最后又回調了onCapabilitiesChanged,那么應該是網絡進度到可用的狀態。

#總結#

我沒有模擬出onLosing和onUnavailable的場景,至少說明他倆的出現的概率現在已經不高了,我們已經通過注釋簡單理解了他倆的場景,這里就不做深入研究了。

通過剛才的實驗,我們得出了一下結論:

1、要想監聽網絡的連接和斷開,應該在onAvailable和onLost中,他們一定會成對出現。

2、其他的幾個回調使用場景會少一點,並且onCapabilitiesChanged會回調多次,所以使用它時我們要慎重,避免重復的操作,但是可以保證最后一次回調,網絡的連接一定是連接成功的。

OK,從這個小小的變化,我們看到了安卓在慢慢變得更好,使用起來更簡潔更優雅,這也加大了某些素質低的廠商想盡辦法后台干點壞事的行為。

今天就到這里,有什么問題大家一起留言討論~

#補充#

1、記得申請權限:

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
 <uses-permission android:name="android.permission.WRITE_SETTINGS" />

尤其是WRITE_SETTINGS,這個需要手動申請,千萬別忘了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM