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

      

  • 相关阅读:
    网页加速的14条优化法则 网站开发与优化
    .NET在后置代码中输入JS提示语句(背景不会变白)
    C语言变量声明内存分配
    SQL Server Hosting Toolkit
    An established connection was aborted by the software in your host machine
    C语言程序设计 2009春季考试时间和地点
    C语言程序设计 函数递归调用示例
    让.Net 程序脱离.net framework框架运行
    C语言程序设计 答疑安排(2009春季 110周) 有变动
    软件测试技术,软件项目管理 实验时间安排 2009春季
  • 原文地址:https://www.cnblogs.com/yizuochengchi2012/p/6289223.html
Copyright © 2011-2022 走看看