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

8FFB96AF-4305-42F4-817F-BAA6F2668577.png
這樣做的具體原因如下:

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;
}
}
}
}