Android 動態監聽網絡 斷網重連


需求:

  網絡連接斷開 彈出popupwindow 當前網絡連接斷開 網絡恢復時popupwindow 消失重新請求網絡。

需求描述完畢 上一張帥圖

  

 

思路:廣播 發送及時消息 斷網flag  popupwindow何時展示 大致就是這些需要考慮

吐槽:好久沒寫了 忙着換工作 趕新項目進度 新項目 用的是Dagger2 + RxJava + Retrofit + RxBus + DataBinding 很酸爽

后面又時間會跟大家分享。歡迎加入QQ群 521039620一塊討論 后面我們會一起討論熱修復 增量更新kotlin等 互相學習~。

直接上代碼:

  廣播代碼:

  

/**
* 使用廣播去監聽網絡
* Created by 鄧鑒恆 on 16/9/13.
  感謝這個哥們兒~ 找不到參考地址了 這里保留他的名字 謝謝了
*/
public class NetStateReceiver extends BroadcastReceiver {

private final static String ANDROID_NET_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
private final static String TAG = NetStateReceiver.class.getSimpleName();

private static boolean isNetAvailable = false;
private static HttpUtil.NetType mNetType;
private static ArrayList<NetChangeObserver> mNetChangeObservers = new ArrayList<NetChangeObserver>();
private static BroadcastReceiver mBroadcastReceiver;

private static BroadcastReceiver getReceiver() {
if (null == mBroadcastReceiver) {
synchronized (NetStateReceiver.class) {
if (null == mBroadcastReceiver) {
mBroadcastReceiver = new NetStateReceiver();
}
}
}
return mBroadcastReceiver;
}

@Override
public void onReceive(Context context, Intent intent) {
mBroadcastReceiver = NetStateReceiver.this;
if (intent.getAction().equalsIgnoreCase(ANDROID_NET_CHANGE_ACTION)) {
if (!HttpUtil.isNetworkAvailable(context)) {
Log.e(this.getClass().getName(), "<--- network disconnected --->");
isNetAvailable = false;
} else {
Log.e(this.getClass().getName(), "<--- network connected --->");
isNetAvailable = true;
mNetType = HttpUtil.getAPNType(context);
}
notifyObserver();
}
}

/**
* 注冊
*
* @param mContext
*/
public static void registerNetworkStateReceiver(Context mContext) {
IntentFilter filter = new IntentFilter();
filter.addAction(ANDROID_NET_CHANGE_ACTION);
mContext.getApplicationContext().registerReceiver(getReceiver(), filter);
}

/**
* 清除
*
* @param mContext
*/
public static void checkNetworkState(Context mContext) {
Intent intent = new Intent();
intent.setAction(ANDROID_NET_CHANGE_ACTION);
mContext.sendBroadcast(intent);
}

/**
* 反注冊
*
* @param mContext
*/
public static void unRegisterNetworkStateReceiver(Context mContext) {
if (mBroadcastReceiver != null) {
try {
mContext.getApplicationContext().unregisterReceiver(mBroadcastReceiver);
} catch (Exception e) {

}
}

}

public static boolean isNetworkAvailable() {
return isNetAvailable;
}

public static HttpUtil.NetType getAPNType() {
return mNetType;
}

private void notifyObserver() {
if (!mNetChangeObservers.isEmpty()) {
int size = mNetChangeObservers.size();
for (int i = 0; i < size; i++) {
NetChangeObserver observer = mNetChangeObservers.get(i);
if (observer != null) {
if (isNetworkAvailable()) {
observer.onNetConnected(mNetType);
} else {
observer.onNetDisConnect();
}
}
}
}
}

/**
* 添加網絡監聽
*
* @param observer
*/
public static void registerObserver(NetChangeObserver observer) {
if (mNetChangeObservers == null) {
mNetChangeObservers = new ArrayList<NetChangeObserver>();
}
mNetChangeObservers.add(observer);
}

/**
* 移除網絡監聽
*
* @param observer
*/
public static void removeRegisterObserver(NetChangeObserver observer) {
if (mNetChangeObservers != null) {
if (mNetChangeObservers.contains(observer)) {
mNetChangeObservers.remove(observer);
}
}
}
}
// 接口:
  
public interface NetChangeObserver {
/**
* 網絡連接回調 type為網絡類型
*/
void onNetConnected(HttpUtil.NetType type);
/**
* 沒有網絡
*/
void onNetDisConnect();
}

  

  BaseActivity:

//網絡觀察者
protected NetChangeObserver mNetChangeObserver = null;
protected NetworkPopupWindow networkWindow;

protected boolean network = true;
 onCreate:
mNetChangeObserver = new NetChangeObserver() {
@Override
public void onNetConnected(HttpUtil.NetType type) {
if (networkWindow != null && networkWindow.isShowing()) {
networkWindow.dismiss();
}
onNetworkConnected(type);
network = true;
}

@Override
public void onNetDisConnect() {
network = false;
onNetworkDisConnected();
}
};
//開啟廣播去監聽 網絡 改變事件
NetStateReceiver.registerObserver(mNetChangeObserver);

//======================baseacivity中重寫
/**
* 網絡連接狀態
* @param type 網絡狀態
*/
protected void onNetworkConnected(HttpUtil.NetType type) {
}

/**
* 網絡斷開的時候調用
*/
protected void onNetworkDisConnected() {
}

//相關類如下 ================================
/**
* 處理網絡斷開的dialog顯示
*/

private View decorView;

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && !network) {
if (networkWindow == null) {
networkWindow = new NetworkPopupWindow(BaseActivity.this);
Rect rect = new Rect();
decorView = getWindow().getDecorView();
decorView.getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top; //狀態欄高度
Log.d("標題欄高度", "onWindowFocusChanged: " + statusBarHeight);
}
decorView.post(() -> networkWindow.showAtLocation(decorView, Gravity.TOP, 0,
0));
}
}

public class NetworkPopupWindow extends PopupWindow {

public NetworkPopupWindow(final Context context) {

LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View mMenuView = inflater.inflate(R.layout.networkpopupwindow, null);

mMenuView.setOnClickListener(v -> context.startActivity(new Intent(Settings.ACTION_SETTINGS)));
// 設置SelectPicPopupWindow的View
this.setContentView(mMenuView);
// 設置SelectPicPopupWindow彈出窗體的寬
this.setWidth(LayoutParams.FILL_PARENT);
// 設置SelectPicPopupWindow彈出窗體的高
this.setHeight(LayoutParams.WRAP_CONTENT);
// 設置SelectPicPopupWindow彈出窗體可點擊
this.setFocusable(false);
// 設置SelectPicPopupWindow彈出窗體動畫效果
// this.setAnimationStyle(R.style.AnimBottom);
// 實例化一個ColorDrawable顏色為半透明
ColorDrawable dw = new ColorDrawable(9000);
// 設置SelectPicPopupWindow彈出窗體的背景
this.setBackgroundDrawable(dw);
}

}
//layout 布局 wifi_off_icon一張圖片 可要可不要
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

  
<TextView
android:layout_width="match_parent"
android:layout_height="45dip"
android:background="#ffdcd0"
android:drawableLeft="@drawable/wifi_off_icon"
android:drawablePadding="12.5dip"
android:gravity="center_vertical"
android:paddingLeft="10dip"
android:text="世界上最遙遠的距離就是沒網。檢查設置"
android:textColor="#665b55" />

</RelativeLayout>

  Application:

@Override
public void onCreate() {
super.onCreate();
  NetStateReceiver.registerNetworkStateReceiver(this);//初始化網絡監聽
}

@Override
public void onLowMemory() {
super.onLowMemory();
NetStateReceiver.unRegisterNetworkStateReceiver(this);
android.os.Process.killProcess(android.os.Process.myPid());
exit();
}

   

  RxBus(沒用到 擴展):

/**
* 使用RxBus 代替 event bus
* Created by kcw001 on 2016/7/21.
*/
public class RxBus {


private static volatile RxBus INSTANCE = new RxBus();

private final Subject<Object,Object> bus;

private final Map<Class<?>,Object> mStickyEventMap;

public RxBus(){
bus = new SerializedSubject<>(PublishSubject.create());
mStickyEventMap = new ConcurrentHashMap<>();//存
}

public static RxBus getDefault(){
if(INSTANCE==null){
synchronized (RxBus.class){
if(INSTANCE==null){
INSTANCE = new RxBus();
}
}
}
return INSTANCE;
}



/**
* 發送事件 單靠一種類型完全解決不了我們的需求 Sticky 方式補充
* @param event
*/
public void post(Object event){
synchronized (mStickyEventMap){
mStickyEventMap.put(event.getClass(),event);
}
bus.onNext(event);
}

/**
* 根據eventType獲取Sticky事件
*/
public <T> T getStickyEvent(Class<T> eventType) {
synchronized (mStickyEventMap) {
return eventType.cast(mStickyEventMap.get(eventType));
}
}




/**
* 根據傳遞的eventType 類型返回eventType的觀察者
*/
public <T> Observable<T> toObservable(Class<T> eventType){
synchronized (mStickyEventMap) {
Observable<T> observable = bus.ofType(eventType);
Object event = mStickyEventMap.get(eventType);
if(event!=null){
return Observable.merge(observable,Observable.create(new Observable.OnSubscribe<T>(){

@Override
public void call(Subscriber<? super T> subscriber) {
subscriber.onNext(eventType.cast(event));
}
}));
}else{
return observable;
}
}
//return bus.ofType(eventType);
}
}

  Activity中(集成baseActivity):

@Override
protected void onNetworkConnected(HttpUtil.NetType type) {
if (!network) {
initUi();//重新請求網絡
network = true;
}
}

@Override
protected void onNetworkDisConnected() {//斷網

}

    

 

大致如上 如有遺漏或者更好的想法 歡迎加群 學習交流

QQ群521039620

 

 

 

 

 

 

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM