zoukankan      html  css  js  c++  java
  • 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

      

  • 相关阅读:
    USTC 软硕讯飞班参考资源
    nginx 负载均衡
    Meidawiki 配置
    10 款实用的jquery插件
    Mongodb 定时释放内存
    互联网产品精神解读
    简单的缓冲区溢出实验
    fatal error C1902: 程序数据库管理器不匹配;请检查安装解决
    C#的override、new、vitutal一例
    SQL Server 2008导入、导出数据库
  • 原文地址:https://www.cnblogs.com/yizuochengchi2012/p/6289223.html
Copyright © 2011-2022 走看看