前言
項(xiàng)目中用到了BroadcastReceiver監(jiān)聽(tīng)網(wǎng)絡(luò)狀態(tài)的改變用以控制下載任務(wù)的暫?;蚶^續(xù),原來(lái)是在AndroidManifest中注冊(cè)了一個(gè)Receiver,然后在Receiver中通過(guò)邏輯判斷執(zhí)行不同操作,本來(lái)是沒(méi)有問(wèn)題的,但這兩天在看官方文檔,發(fā)現(xiàn)這種方式在7.0版本及以上失效了,官方文檔說(shuō)明如下:

這樣做的具體原因如下:

這里可以知道,當(dāng)很多應(yīng)用在AndroidManifest中注冊(cè)同一個(gè)廣播時(shí),系統(tǒng)會(huì)加載所有以這種方式注冊(cè)了這個(gè)廣播的app,這樣會(huì)對(duì)設(shè)備性能和用戶體驗(yàn)造成重大影響。所以為了解決這個(gè)問(wèn)題,最好不用這種注冊(cè)方式。監(jiān)聽(tīng)用戶網(wǎng)絡(luò)切換應(yīng)該是每個(gè)app都會(huì)干的事,所以谷歌直接就禁止了在AndroidManifest中注冊(cè)這個(gè)廣播。既然如此,就來(lái)復(fù)習(xí)一下創(chuàng)建廣播接收器的相關(guān)知識(shí)。
廣播接收器的定義
個(gè)人理解廣播接收器就類似觀察者模式,當(dāng)系統(tǒng)或者其他app發(fā)出一個(gè)廣播的時(shí)候,只要你的app對(duì)這個(gè)消息感興趣的話(注冊(cè)了這個(gè)廣播)就會(huì)收到這個(gè)消息,然后你就可以對(duì)這個(gè)消息進(jìn)行處理,但如何注冊(cè)廣播并接收消息呢?下面介紹兩種方法(這里以接收網(wǎng)絡(luò)狀態(tài)切換為例):
****注意事項(xiàng)****
由于這里要監(jiān)聽(tīng)網(wǎng)絡(luò)狀態(tài),所以首先必須加上相關(guān)權(quán)限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-
****動(dòng)態(tài)注冊(cè)法****
1,新建ConnectivityReceiver類繼承BroadcastReceiver類,覆蓋onReceive方法,寫入相關(guān)邏輯
2,在相關(guān)Activity中新建ConnectivityReceiver對(duì)象并初始化,新建IntentFilter對(duì)象并初始化,設(shè)置IntentFilter的Action
3,使用registerReceiver(BroadcastReceiver,IntentFilter)方法注冊(cè)廣播。
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中注冊(cè)的,在onStop中記得反注冊(cè),如果在onCreate中注冊(cè)的,記得在onDestroy中反注冊(cè),不然會(huì)內(nèi)存泄漏,反注冊(cè)調(diào)用unregisterReceier(BroadcastReceiver)就行
-
****AndroidManifest.xml注冊(cè)法(個(gè)人感覺(jué)非必要的話最好使用動(dòng)態(tài)注冊(cè)的方式)****
步驟
1,新建ConnectivityReceiver類繼承BroadcastReceiver類,覆蓋onReceive方法
2,在AndroidManifest中注冊(cè)<receiver></receiver>節(jié)點(diǎn),exported屬性如果為true表示接收器接收除本應(yīng)用(準(zhǔn)確來(lái)說(shuō)是同一個(gè)進(jìn)程)以外的應(yīng)用發(fā)送過(guò)來(lái)的消息,如果為false表示接收器只接受本應(yīng)用發(fā)送的消息
<receiver android:name=".ConnectivityReceiver" android:exported="false">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
3,在onReceiver方法中寫入相關(guān)邏輯
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; } } } }