一起Talk Android吧(第五百二十七回:监听网络状态)

Posted talk_8

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起Talk Android吧(第五百二十七回:监听网络状态)相关的知识,希望对你有一定的参考价值。

文章目录


各位看官们大家好,上一回中咱们说的例子是"获取网络状态",本章回介绍的例子是" 监听网络状态"。闲话休提,言归正转,让我们一起Talk android吧!

概念介绍

看官们,我们在上一章回中介绍了如何获取网络状态,不过代码中使用的相关类已经被弃用,本章回中将介绍另外一种获取网络连接状态的方法:通过回调方法监听网络状态。该方法不但可以获取到网络连接状态,还可以获取到其它网络信息。

实现方法

  1. 申请网络操作相关的权限,静态申请就可以;
  2. 获取网络管理器:ConnectivityManager
  3. 创建监听网络状态的接口并且重写接口中的方法,这些方法用来监听网络状态;
  4. 注册监听网络状态的监听器,通过网络管理器的requestNetwork()方法实现;
  5. 在监听器的回调方法中通过特定的capability获取网络连接状态;

示例代码

    private void requestNetworkState() 
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkRequest networkRequest = new NetworkRequest.Builder().build();
        ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() 
            //连接上网络时回调
            @Override
            public void onAvailable(@NonNull Network network) 
                super.onAvailable(network);
            

            @Override
            public void onLosing(@NonNull Network network, int maxMsToLive) 
                super.onLosing(network, maxMsToLive);
            

            //无网络连接时回调
            @Override
            public void onLost(@NonNull Network network) 
                super.onLost(network);
            

            //不会回调
            @Override
            public void onUnavailable() 
                super.onUnavailable();
            

            @Override
            public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) 
                super.onCapabilitiesChanged(network, networkCapabilities);
                //仅表示有联网的能力
               Log.d(TAG, "onCapabilitiesChanged: cab: "+networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
                //表示网络已经连接并且可用
               Log.d(TAG, "onCapabilitiesChanged: valid: "+networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
            

            @Override
            public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties linkProperties) 
                super.onLinkPropertiesChanged(network, linkProperties);
            

            @Override
            public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) 
                super.onBlockedStatusChanged(network, blocked);
            
        ;
        connectivityManager.requestNetwork(networkRequest,networkCallback);
    

为了使用方便,我们把所有功能封装到了一个方法中.代码中使用了networkReques类,通过Build方法创建就可以,我们不做详细介绍。重点关注NetworkCallback
接口中的回调方法,我们相关方法中添加了注释,方便大家理解。

最常用的是onCapabilitiesChanged()方法,网络状态发生变化时它就会被调用,我们在该方法中通过检查NET_CAPABILITY_VALIDATED这个capability来判断网络是否连接,这样就可以像上一章回中一样获取到网络的连接状态。

官方还提供了其它的capability供我们使用,因为数量比较多,这里不详细列出,大家可以参考官方文档。

onLinkPropertiesChanged()方法也是比较常用的方法,网络状态发生变化时,该方法也会被调用,我们可以在方法中获取到网址,DNS等信息。我要这里就不介绍了,大家可以自己动手去实践。

经验总结

Network类被弃用后官方推荐使用NetworkCapabilitiesLinkProperties这两个类,它们包含了全部的网络信息。结合我的项目经验,监听网络状态的方法比上一章回中介绍的获取网络连接状态的方法要好用一些,因为监听网络状态是在后台,也就是异步操作,我们可以在前台做其它事情,如果有网络状态发生了变化,那么我们只需要响应监听器就可以。上一章回中获取网络连接状态的方法是同步的,我们只能实时地查看网络连接状态。因此,我们更加推荐大家使用本章回中介绍的监听器方法。而且这两个类相关的方法是在API21就提供了,版本比较早,兼容的范围也很广。

看官们,关于"监听网络状态"的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

一起Talk Android吧(第五百一十七回:绘制波浪效果)

文章目录


各位看官们大家好,上一回中咱们说的例子是"绘制压力扩散图",这一回中咱们说的例子是"绘制波浪效果"。闲话休提,言归正转, 让我们一起Talk Android吧!

整体思路

我们在这里说的波浪效果就是类似正弦波一样的图形,它在不断的移动,产生类似波浪效果,详细如下图所示:我们使用贝塞尔曲线来画波形,把波形通过动画的形式
来移动。这样就产生了波浪的效果。

实现方法

  1. 自定义波浪组件,主要重写它的布局和绘制方法;
  2. 创建动画文件,我们使用值动画;
  3. 在布局中添加自定义的波浪控件;

示例代码

public class WaveView extends View 
    private int  width = 0;
    private int height = 0;
    private int baseLine = 0;// 基线,用于控制水位上涨的,这里是写死了没动,你可以不断的设置改变。
    private Paint mPaint;
    private int waveHeight = 100;// 波浪的最高度
    private int waveWidth  ;//波长
    private float offset =0f;//偏移量
    public WaveView(Context context, AttributeSet attrs) 
        super(context, attrs);
        initView();
    
 
    /**
     * 不断的更新偏移量,并且循环。
     */
    private void updateXControl()
        //设置一个波长的偏移
        ValueAnimator mAnimator = ValueAnimator.ofFloat(0,waveWidth);
        mAnimator.setInterpolator(new LinearInterpolator());
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() 
 
            @Override
            public void onAnimationUpdate(ValueAnimator animation) 
                float animatorValue = (float)animation.getAnimatedValue() ;
                offset = animatorValue;//不断的设置偏移量,并重画
                postInvalidate();
            
        );
        mAnimator.setDuration(1000);
        mAnimator.setRepeatCount(ValueAnimator.INFINITE);
        mAnimator.start();
    
 
    @Override
    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);
        canvas.drawPath(getPath(),mPaint);
    
    //初始化paint,没什么可说的。
    private void initView()
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);
 
    
 
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
        super.onLayout(changed, left, top, right, bottom);
        width = getMeasuredWidth();//获取屏幕宽度
        height = getMeasuredHeight();//获取屏幕高度
        waveWidth = width;
        baseLine = height/2;
        updateXControl();
    
 
    /**
     * 核心代码,计算path
     * @return
     */
    private Path  getPath()
        int itemWidth = waveWidth/2;//半个波长
        Path mPath = new Path();
        mPath.moveTo(-itemWidth * 3, baseLine);//起始坐标
        //核心的代码就是这里
        for (int i = -3; i < 2; i++) 
            int startX = i * itemWidth;
            mPath.quadTo(
                    startX + itemWidth/2 + offset,//控制点的X,(起始点X + itemWidth/2 + offset)
                    getWaveHeigh( i ),//控制点的Y
                    startX + itemWidth + offset,//结束点的X
                    baseLine//结束点的Y
            );//只需要处理完半个波长,剩下的有for循环自已就添加了。
        
        //下面这三句话很重要,它是形成了一封闭区间,让曲线以下的面积填充一种颜色,大家可以把这3句话注释了看看效果。
        mPath.lineTo(width,height);
        mPath.lineTo(0,height);
        mPath.close();
        return  mPath;
    
    //奇数峰值是正的,偶数峰值是负数
    private int getWaveHeigh(int num)
        if(num % 2 == 0)
            return baseLine + waveHeight;
        
        return baseLine - waveHeight;
    

看官们,关于"绘制波浪效果"的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

以上是关于一起Talk Android吧(第五百二十七回:监听网络状态)的主要内容,如果未能解决你的问题,请参考以下文章

一起Talk Android吧(第五百一十七回:绘制波浪效果)

一起Talk Android吧(第四百二十七回:在Android中使用MQTT通信一)

一起Talk Android吧(第五百零七回:图片滤镜ImageFilterView)

一起Talk Android吧(第三百四十七回:解析JSON数组二)

一起Talk Android吧(第三百八十七回:LiveData)

一起Talk Android吧(第三百八十七回:LiveData)