android 自定义网络变化时全局提醒

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yrmao9893/article/details/81318524

前言:今天在鸿洋大神的公众号中看到一篇文章,叫10分钟让你实现在APP中对网络状态变化进行全局提醒。这在APP开发中是一个硬性需求,虽然我开发的app并没有要求,但我觉得这个功能有必要亲手实现一下。当然我也借鉴了作者的一些思路

参考文章:https://mp.weixin.qq.com/s/W9U7uzXRYcqCmgbX3gbbKg

实现思路:1、定时获取当前网络状态

                  2、利用广播发送当前网络状态,并且触发网络状态改变的监听

                  3、在baseActivity中实现网络状态改变的监听,并作出相应的响应(例如显示没有网络的布局)

代码实现:

             .定义接收网络变化的广播,广播我这边用的的动态广播,本来也打算用静态广播的但是看别人的评论说,android P下面有问题,所以就没用了

public class CheckNetworkStatusChangeReceiver extends BroadcastReceiver {
    public static final String EVENT = "event";
    public static final String ACTION="action";
    private CheckNetworkStatusChangeListener mCheckNetworkStatusChangeListener;

    public CheckNetworkStatusChangeReceiver() {

    }

    public void setCheckNetworkStatusChangeListener(CheckNetworkStatusChangeListener mCheckNetworkStatusChangeListener) {
        this.mCheckNetworkStatusChangeListener = mCheckNetworkStatusChangeListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        CheckNetworkStatusChangeListener.Status mStatus = (CheckNetworkStatusChangeListener.Status) intent.getSerializableExtra(EVENT);
        mCheckNetworkStatusChangeListener.onEvent(mStatus);
    }
}

            网络状态监听类

public interface CheckNetworkStatusChangeListener {
    
    void onEvent(Status status);

    /**
     * 网络状态
     * TYPE_UN_NETWORK 沒有网络
     * TYPE_WIFI WiFi连接
     * TYPE_MOBILE 移动数据
     */
    enum Status {
        TYPE_UN_NETWORK,
        TYPE_WIFI,
        TYPE_MOBILE,
    }
}

监听事件,检查到网络状态时会调用

void onEvent(Status status);

检测当前网络状态

public class NetworkUtil {
    /**
     * 获取当前网络类型 CheckNetworkStatusChangeListener.Status
     *
     * @return 返回网络类型 CheckNetworkStatusChangeListener.Status
     */
    public static CheckNetworkStatusChangeListener.Status getNetworkConnectionType(Context context) {
        //获取连接管理器
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager == null)
            return CheckNetworkStatusChangeListener.Status.TYPE_UN_NETWORK;
        //获取网络连接信息
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isAvailable()) {
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                return CheckNetworkStatusChangeListener.Status.TYPE_WIFI;
            }
            if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                return CheckNetworkStatusChangeListener.Status.TYPE_MOBILE;
            }
        }
        return CheckNetworkStatusChangeListener.Status.TYPE_UN_NETWORK;
    }
}

实现每秒检测1次网络状态,因为是耗时操作所有在子线程中去获取当前网络状态

扫描二维码关注公众号,回复: 3591712 查看本文章
 @Override
    protected void onResume() {
        super.onResume();
        new Thread(mRunnable).start();
    }

    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {

            //实现每隔一秒检测一次网络
            while (true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                CheckNetworkStatusChangeListener.Status status = NetworkUtil.getNetworkConnectionType(BaseActivity.this);
                Message message = new Message();
                message.obj = status;
                simpleHandler.sendMessage(message);
            }

        }
    };

检测网络状态后发送Message到handle,handle去发送广播,这注意handle内存泄漏

/**
 * @ Author yemao
 * @ Email [email protected]
 * @ Date 2018/7/31
 * @ Des自定义Handler,使用弱引用防止内存溢出
 */
public class SimpleHandler<T extends Activity> extends Handler {
    WeakReference<T> weakReference;

    public SimpleHandler(T t) {
        this.weakReference = new WeakReference<>(t);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (weakReference.get() != null) {
            //发送广播
            Intent mCheckNetworkIntent = new Intent();
            mCheckNetworkIntent.setAction(CheckNetworkStatusChangeReceiver.ACTION);
            CheckNetworkStatusChangeListener.Status status= (CheckNetworkStatusChangeListener.Status) msg.obj;
            mCheckNetworkIntent.putExtra(CheckNetworkStatusChangeReceiver.EVENT,status);
            weakReference.get().sendBroadcast(mCheckNetworkIntent);
        }
    }

}

到这基本上就窜起来了,看下baseActivity完整代码

/**
 * @ Author YeMao
 * @ Email [email protected]
 * @ Date 2018/7/31
 * @ Des Activity 基类
 */
public class BaseActivity extends AppCompatActivity implements CheckNetworkStatusChangeListener {
    private CheckNetworkStatusChangeReceiver mCheckNetworkStatusChangeReceiver;
    private String LOG = BaseActivity.class.getSimpleName();
    SimpleHandler<BaseActivity> simpleHandler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mCheckNetworkStatusChangeReceiver = new CheckNetworkStatusChangeReceiver();
        mCheckNetworkStatusChangeReceiver.setCheckNetworkStatusChangeListener(this);
        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(CheckNetworkStatusChangeReceiver.ACTION);
        registerReceiver(mCheckNetworkStatusChangeReceiver, mIntentFilter);
        simpleHandler = new SimpleHandler<BaseActivity>(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        new Thread(mRunnable).start();
    }

    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {

            //实现每隔一秒检测一次网络
            while (true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                CheckNetworkStatusChangeListener.Status status = NetworkUtil.getNetworkConnectionType(BaseActivity.this);
                Message message = new Message();
                message.obj = status;
                simpleHandler.sendMessage(message);
            }

        }
    };


    @Override
    public void onEvent(Status status) {
        Log.w(LOG, "status: " + status.name());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mCheckNetworkStatusChangeReceiver);
        simpleHandler.removeCallbacks(mRunnable);
    }


}

我们运行一下,看下结果

07-31 19:12:14.069 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_WIFI
07-31 19:12:14.172 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_WIFI
07-31 19:12:14.429 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_WIFI
07-31 19:12:14.975 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_WIFI
07-31 19:12:15.071 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_UN_NETWORK
07-31 19:12:15.193 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_UN_NETWORK
07-31 19:12:15.446 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_UN_NETWORK
07-31 19:12:15.959 13865-13865/com.yr.simple W/BaseActivity: status: TYPE_UN_NETWORK

当网络变化时,调用onEvent()的打印信息

那么下一步就是在onEvent()判断网络状态,没有网络时的页面提示,当然你也可以做其他操作我这只提供思路

1.自定义layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="@color/gray"
    android:layout_height="50dp">
    <TextView
        android:id="@+id/tv_network_status"
        android:layout_centerInParent="true"
        android:text="@string/not_network"
        android:textColor="@color/red"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</RelativeLayout>

2.BaseActivity关键代码

  @Override
    public void setContentView(int layoutResID) {
        LinearLayout mRootLayout = findViewById(R.id.root_linear_layout);
        //将网络状态view添加到根视图
        mNetworkStatusLayout = new NetworkStatusLayout(this);
        //默认隐藏状态
        mNetworkStatusLayout.setVisibility(View.GONE);
        mRootLayout.addView(mNetworkStatusLayout, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        //将子类的layout,添加到根目录
        View mContentView = LayoutInflater.from(this).inflate(layoutResID, null);
        mRootLayout.addView(mContentView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    }

动态显示隐藏NetworkStatusLayout

 @Override
    public void onEvent(Status status) {
        Log.w(LOG, "status: " + status.name());
        if (status == Status.TYPE_UN_NETWORK) {
            if (mNetworkStatusLayout.getVisibility() == View.GONE)
                mNetworkStatusLayout.setVisibility(View.VISIBLE);
        } else {
            if (mNetworkStatusLayout.getVisibility() == View.VISIBLE)
                mNetworkStatusLayout.setVisibility(View.GONE);
        }
    }

运行一下看下效果

然后进入优化工作

可能有些页面不需要显示,添加变量checkNetworkStatusChangeListenerEnable判断是否要显示
 

private boolean checkNetworkStatusChangeListenerEnable=true;
public void setCheckNetworkStatusChangeListenerEnable(boolean checkNetworkStatusChangeListener) {
        this.checkNetworkStatusChangeListenerEnable = checkNetworkStatusChangeListener;
}
    @Override
    public void onEvent(Status status) {
        Log.w(LOG, "status: " + status.name());
        if (checkNetworkStatusChangeListenerEnable)
            return;
        if (status == Status.TYPE_UN_NETWORK) {
            if (mNetworkStatusLayout.getVisibility() == View.GONE)
                mNetworkStatusLayout.setVisibility(View.VISIBLE);
        } else {
            if (mNetworkStatusLayout.getVisibility() == View.VISIBLE)
                mNetworkStatusLayout.setVisibility(View.GONE);
        }
    }

到这基本上大功告成了,BaseActivity完整代码
 

public class BaseActivity extends AppCompatActivity implements CheckNetworkStatusChangeListener {
    private CheckNetworkStatusChangeReceiver mCheckNetworkStatusChangeReceiver;
    private String LOG = BaseActivity.class.getSimpleName();
    private SimpleHandler<BaseActivity> simpleHandler;
    private NetworkStatusLayout mNetworkStatusLayout;
    private boolean checkNetworkStatusChangeListenerEnable=true;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_base);
        init();
    }

    @Override
    public void setContentView(int layoutResID) {
        LinearLayout mRootLayout = findViewById(R.id.root_linear_layout);
        //将网络状态view添加到根视图
        mNetworkStatusLayout = new NetworkStatusLayout(this);
        //默认隐藏状态
        mNetworkStatusLayout.setVisibility(View.GONE);
        mRootLayout.addView(mNetworkStatusLayout, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        //将子类的layout,添加到根目录
        View mContentView = LayoutInflater.from(this).inflate(layoutResID, null);
        mRootLayout.addView(mContentView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    }

    private void init() {
        mCheckNetworkStatusChangeReceiver = new CheckNetworkStatusChangeReceiver();
        mCheckNetworkStatusChangeReceiver.setCheckNetworkStatusChangeListener(this);
        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(CheckNetworkStatusChangeReceiver.ACTION);
        registerReceiver(mCheckNetworkStatusChangeReceiver, mIntentFilter);
        simpleHandler = new SimpleHandler<BaseActivity>(this);
    }

    public void setCheckNetworkStatusChangeListenerEnable(boolean checkNetworkStatusChangeListener) {
        this.checkNetworkStatusChangeListenerEnable = checkNetworkStatusChangeListener;
    }

    @Override
    protected void onResume() {
        super.onResume();
        new Thread(mRunnable).start();
    }

    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {

            //实现每隔一秒检测一次网络
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                CheckNetworkStatusChangeListener.Status status = NetworkUtil.getNetworkConnectionType(BaseActivity.this);
                Message message = new Message();
                message.obj = status;
                simpleHandler.sendMessage(message);
            }

        }
    };


    @Override
    public void onEvent(Status status) {
        Log.w(LOG, "status: " + status.name());
        if (checkNetworkStatusChangeListenerEnable)
            return;
        if (status == Status.TYPE_UN_NETWORK) {
            if (mNetworkStatusLayout.getVisibility() == View.GONE)
                mNetworkStatusLayout.setVisibility(View.VISIBLE);
        } else {
            if (mNetworkStatusLayout.getVisibility() == View.VISIBLE)
                mNetworkStatusLayout.setVisibility(View.GONE);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mCheckNetworkStatusChangeReceiver);
        simpleHandler.removeCallbacks(mRunnable);
    }


}

如何使用,activity继承自BaseActivity
 

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("我是首页");
    }
}

好了,谢谢大家阅读,如有问题请戳我哦!

猜你喜欢

转载自blog.csdn.net/yrmao9893/article/details/81318524