天天看點

android監聽網絡切換,監聽網絡狀态切換事件

前言

項目中用到了BroadcastReceiver監聽網絡狀态的改變用以控制下載下傳任務的暫停或繼續,原來是在AndroidManifest中注冊了一個Receiver,然後在Receiver中通過邏輯判斷執行不同操作,本來是沒有問題的,但這兩天在看官方文檔,發現這種方式在7.0版本及以上失效了,官方文檔說明如下:

android監聽網絡切換,監聽網絡狀态切換事件

8FFB96AF-4305-42F4-817F-BAA6F2668577.png

這樣做的具體原因如下:

android監聽網絡切換,監聽網絡狀态切換事件

image.png

這裡可以知道,當很多應用在AndroidManifest中注冊同一個廣播時,系統會加載所有以這種方式注冊了這個廣播的app,這樣會對裝置性能和使用者體驗造成重大影響。是以為了解決這個問題,最好不用這種注冊方式。監聽使用者網絡切換應該是每個app都會幹的事,是以谷歌直接就禁止了在AndroidManifest中注冊這個廣播。既然如此,就來複習一下建立廣播接收器的相關知識。

廣播接收器的定義

個人了解廣播接收器就類似觀察者模式,當系統或者其他app發出一個廣播的時候,隻要你的app對這個消息感興趣的話(注冊了這個廣播)就會收到這個消息,然後你就可以對這個消息進行處理,但如何注冊廣播并接收消息呢?下面介紹兩種方法(這裡以接收網絡狀态切換為例):

****注意事項****

由于這裡要監聽網絡狀态,是以首先必須加上相關權限

****動态注冊法****

1,建立ConnectivityReceiver類繼承BroadcastReceiver類,覆寫onReceive方法,寫入相關邏輯

2,在相關Activity中建立ConnectivityReceiver對象并初始化,建立IntentFilter對象并初始化,設定IntentFilter的Action

3,使用registerReceiver(BroadcastReceiver,IntentFilter)方法注冊廣播。

public class MainActivity extends AppCompatActivity{

...

private ConnectivityReceiver connectivityReceiver;

private void registerNetReceiver(){

connectivityReceiver = new ConnectivityReceiver();

IntentFilter intentFilter = new IntentFilter();

intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

registerReceiver(connectivityReceiver,intentFilter);

}

...

}

4,如果在onStart中注冊的,在onStop中記得反注冊,如果在onCreate中注冊的,記得在onDestroy中反注冊,不然會記憶體洩漏,反注冊調用unregisterReceier(BroadcastReceiver)就行

****AndroidManifest.xml注冊法(個人感覺非必要的話最好使用動态注冊的方式)****

步驟

1,建立ConnectivityReceiver類繼承BroadcastReceiver類,覆寫onReceive方法

2,在AndroidManifest中注冊節點,exported屬性如果為true表示接收器接收除本應用(準确來說是同一個程序)以外的應用發送過來的消息,如果為false表示接收器隻接受本應用發送的消息

3,在onReceiver方法中寫入相關邏輯

public class ConnectivityReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo info = connectivityManager.getActiveNetworkInfo();

if(info == null){

Toast.makeText(context, "no network", Toast.LENGTH_SHORT).show();

}else{

switch (info.getType()){

case ConnectivityManager.TYPE_WIFI:

Toast.makeText(context, "wifi", Toast.LENGTH_SHORT).show();

break;

case ConnectivityManager.TYPE_MOBILE:

Toast.makeText(context, "mobile", Toast.LENGTH_SHORT).show();

break;

}

}

}

}