Android使用觀察者模式Observer實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)監(jiān)聽
在Android開發(fā)過程中,很多時候都會用到當(dāng)前網(wǎng)絡(luò)的狀態(tài)判斷以及網(wǎng)絡(luò)狀況發(fā)生變化的時候做出相應(yīng)的反應(yīng),要想監(jiān)聽網(wǎng)絡(luò)狀態(tài),用觀察者模式再合適不過了,廢話不多說,直接上代碼。
觀察者模式屬于面向?qū)ο蟮?3中設(shè)計(jì)模式之一,不了解的同學(xué)請自行Google
既然用觀察者模式,自然離不開觀察者模式里最重要的兩個類Subject和Ovserver了
Subjcet接口:
/**
* Description: observer subject
* author: Wang
* date: 11/28/16 11:19 AM
*
* Copyright©2016 by wang. All rights reserved.
*/
public interface NetConnectionSubject {
/**
* 注冊觀察者
*
* @param observer
*/
public void addNetObserver(NetConnectionObserver observer);
/**
* 移除觀察者
*
* @param observer
*/
public void removeNetObserver(NetConnectionObserver observer);
/**
* 狀態(tài)更新通知
*
* @param type
*/
public void notifyNetObserver(int type);
}
Observer接口:
/**
* Description: observer
* author: Wang
* date: 11/28/16 11:20 AM
*
* Copyright©2016 by wang. All rights reserved.
*/
public interface NetConnectionObserver {
/**
* 通知觀察者更改狀態(tài)
*
* @param type
*/
public void updateNetStatus(int type);
}
在Android里,最適合實(shí)現(xiàn)Subject類的,莫過于Application了,因?yàn)樗治ㄒ欢疑芷诰褪沁@個App的生命周期:
/**
* Description: App's application should extend this class
* author: Wang
* date: 11/28/16 10:34 AM
*
* Copyright©2016 by wang. All rights reserved.
*/
public abstract class BaseApplication extends Application implements NetConnectionSubject {
protected static BaseApplication instance;
private int currentNetType = -1;
private List<NetConnectionObserver> observers = new ArrayList<>();
public static BaseApplication getInstance() {
return instance;
}
/**
* current net connection type
*
* @return
*/
public int getCurrentNetType() {
return currentNetType;
}
/**
* current net connection status
*
* @return
*/
public boolean isNetConnection() {
return currentNetType == NetWorkUtil.NET_NO_CONNECTION ? false : true;
}
@Override
public void onCreate() {
super.onCreate();
instance = this;
currentNetType = NetWorkUtil.getConnectionType(this);
}
@Override
public void addNetObserver(NetConnectionObserver observer) {
if (!observers.contains(observer)) {
observers.add(observer);
}
}
@Override
public void removeNetObserver(NetConnectionObserver observer) {
if (observers != null && observers.contains(observer)) {
observers.remove(observer);
}
}
@Override
public void notifyNetObserver(int type) {
/**
* 避免多次發(fā)送相同的網(wǎng)絡(luò)狀態(tài)
*/
if (currentNetType == type) {
return;
} else {
currentNetType = type;
if (observers != null && observers.size() > 0) {
for (NetConnectionObserver observer : observers) {
observer.updateNetStatus(type);
}
}
}
}
}
具體誰要實(shí)現(xiàn)Observer接口,就要看具體場景了,這里以Activity為栗子吧:
/**
* Description: TODO
* author: WangKunHui
* date: 16/12/30 下午3:08
* <p>
* Copyright©2016 by wang. All rights reserved.
*/
public class TestActivity extends Activity implements NetConnectionObserver {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**省略一些方法**/
BaseApplication.getInstance().addNetObserver(this);
}
@Override
public void updateNetStatus(int type) {
//當(dāng)監(jiān)聽網(wǎng)絡(luò)狀態(tài)發(fā)生變化 這里會及時的收到回饋
}
@Override
protected void onDestroy() {
super.onDestroy();
BaseApplication.getInstance().removeNetObserver(this);
}
}
這里有個地方一定要注意:當(dāng)Activity銷毀的時候,一定要把這個觀察者從觀察者隊(duì)列里移除掉!否者會發(fā)生內(nèi)存泄漏
到這里,觀察者模式已經(jīng)寫完了,謝謝收看。
讀者:你是不是忘了點(diǎn)什么,說好的網(wǎng)絡(luò)監(jiān)聽呢?
我:Easy easy~ 剛剛只不過是中場休息
如果只有上面那么多的話,是不能監(jiān)聽網(wǎng)絡(luò)狀態(tài)的,想要監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化,還得靠我們的廣播接收者啊,有請:
/**
* Description: 網(wǎng)絡(luò)連接狀態(tài)的監(jiān)聽
* author: Wang
* date: 16/8/3 下午10:54
*
* Copyright©2016 by wang. All rights reserved.
*/
public class NetConnectionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
int connectionType = NetWorkUtil.getConnectionType(context);
/**
* 更改網(wǎng)絡(luò)狀態(tài)
*/
if (BaseApplication.getInstance() != null) {
BaseApplication.getInstance().notifyNetObserver(connectionType);
}
}
}
}
NetWorkUtil:
/**
* @author Wang
* @version 1.0.0
* @description 網(wǎng)絡(luò)操作工具類
* @create 2014-2-18 上午09:22:30
* @company
*/
public class NetWorkUtil {
/**
* 無網(wǎng)絡(luò)鏈接
*/
public static final int NET_NO_CONNECTION = 0;
/**
* wifi
*/
public static final int NET_TYPE_WIFI = 1;
public static final int NET_TYPE_2G = 2;
public static final int NET_TYPE_3G = 3;
public static final int NET_TYPE_4G = 4;
/**
* 未知的網(wǎng)絡(luò)類型
*/
public static final int NET_TYPE_UNKNOWN = 5;
/**
* 獲取網(wǎng)絡(luò)類型
*
* @param context
* @return
*/
public static int getConnectionType(Context context) {
int netType = NET_NO_CONNECTION;
NetworkInfo networkInfo = ((ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (networkInfo == null) {
netType = NET_NO_CONNECTION;
} else {
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
netType = NET_TYPE_WIFI;
} else {
int networkType = networkInfo.getSubtype();
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN: //api<8 : replace by 11
netType = NET_TYPE_2G;
break;
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B: //api<9:replace by 14
case TelephonyManager.NETWORK_TYPE_EHRPD: //api<11:replace by 12
case TelephonyManager.NETWORK_TYPE_HSPAP: //api<13:replace by 15
netType = NET_TYPE_3G;
break;
case TelephonyManager.NETWORK_TYPE_LTE: //api<11:replace by 13
netType = NET_TYPE_4G;
break;
default:
String subType = networkInfo.getSubtypeName();
if (subType.equalsIgnoreCase("TD-SCDMA") ||
subType.equalsIgnoreCase("WCDMA") ||
subType.equalsIgnoreCase("CDMA2000")) {
netType = NET_TYPE_3G;
} else {
netType = NET_TYPE_UNKNOWN;
}
break;
}
}
}
return netType;
}
}
好了,到這里,標(biāo)題上所有的內(nèi)容已經(jīng)寫完了,最后,別忘了權(quán)限和注冊廣播接收者。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android事件分發(fā)機(jī)制(上) ViewGroup的事件分發(fā)
這篇文章主要為大家詳細(xì)介紹了Android ViewGroup的事件分發(fā)機(jī)制上篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01
Android巧用ViewPager實(shí)現(xiàn)左右循環(huán)滑動圖片
這篇文章主要為大家詳細(xì)介紹了Android巧用ViewPager實(shí)現(xiàn)左右循環(huán)滑動圖片的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-05-05
Android編程實(shí)現(xiàn)的手寫板和涂鴉功能
這篇文章主要介紹了Android編程實(shí)現(xiàn)的手寫板和涂鴉功能,涉及Android界面布局及圖形繪制功能相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-01-01
Android開發(fā)判斷一個app應(yīng)用是否在運(yùn)行的方法詳解
這篇文章主要介紹了Android開發(fā)判斷一個app應(yīng)用是否在運(yùn)行的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android判斷應(yīng)用運(yùn)行狀態(tài)的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-11-11
解決video標(biāo)簽在安卓webview下無法自動播放問題
這篇文章主要介紹了video標(biāo)簽在安卓webview下無法自動播放問題的解決方法 ,需要的朋友可以參考下2014-03-03

