Android使用觀察者模式Observer實現(xiàn)網(wǎng)絡狀態(tài)監(jiān)聽
在Android開發(fā)過程中,很多時候都會用到當前網(wǎng)絡的狀態(tài)判斷以及網(wǎng)絡狀況發(fā)生變化的時候做出相應的反應,要想監(jiān)聽網(wǎng)絡狀態(tài),用觀察者模式再合適不過了,廢話不多說,直接上代碼。
觀察者模式屬于面向對象的23中設計模式之一,不了解的同學請自行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里,最適合實現(xiàn)Subject類的,莫過于Application了,因為它全局唯一而且生命周期就是這個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)絡狀態(tài)
*/
if (currentNetType == type) {
return;
} else {
currentNetType = type;
if (observers != null && observers.size() > 0) {
for (NetConnectionObserver observer : observers) {
observer.updateNetStatus(type);
}
}
}
}
}
具體誰要實現(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) {
//當監(jiān)聽網(wǎng)絡狀態(tài)發(fā)生變化 這里會及時的收到回饋
}
@Override
protected void onDestroy() {
super.onDestroy();
BaseApplication.getInstance().removeNetObserver(this);
}
}
這里有個地方一定要注意:當Activity銷毀的時候,一定要把這個觀察者從觀察者隊列里移除掉!否者會發(fā)生內存泄漏
到這里,觀察者模式已經寫完了,謝謝收看。
讀者:你是不是忘了點什么,說好的網(wǎng)絡監(jiān)聽呢?
我:Easy easy~ 剛剛只不過是中場休息
如果只有上面那么多的話,是不能監(jiān)聽網(wǎng)絡狀態(tài)的,想要監(jiān)聽網(wǎng)絡狀態(tài)的變化,還得靠我們的廣播接收者啊,有請:
/**
* Description: 網(wǎng)絡連接狀態(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)絡狀態(tài)
*/
if (BaseApplication.getInstance() != null) {
BaseApplication.getInstance().notifyNetObserver(connectionType);
}
}
}
}
NetWorkUtil:
/**
* @author Wang
* @version 1.0.0
* @description 網(wǎng)絡操作工具類
* @create 2014-2-18 上午09:22:30
* @company
*/
public class NetWorkUtil {
/**
* 無網(wǎng)絡鏈接
*/
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)絡類型
*/
public static final int NET_TYPE_UNKNOWN = 5;
/**
* 獲取網(wǎng)絡類型
*
* @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;
}
}
好了,到這里,標題上所有的內容已經寫完了,最后,別忘了權限和注冊廣播接收者。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android事件分發(fā)機制(上) ViewGroup的事件分發(fā)
這篇文章主要為大家詳細介紹了Android ViewGroup的事件分發(fā)機制上篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01
Android巧用ViewPager實現(xiàn)左右循環(huán)滑動圖片
這篇文章主要為大家詳細介紹了Android巧用ViewPager實現(xiàn)左右循環(huán)滑動圖片的相關資料,感興趣的小伙伴們可以參考一下2016-05-05
Android開發(fā)判斷一個app應用是否在運行的方法詳解
這篇文章主要介紹了Android開發(fā)判斷一個app應用是否在運行的方法,結合實例形式較為詳細的分析了Android判斷應用運行狀態(tài)的相關操作技巧與注意事項,需要的朋友可以參考下2017-11-11

