android 5.0 以上监听网络变化

前言#

大家好,大概有一个多月没有更新博客了,我是干什么去了呢?很明显,程序员当然要加班……这一次跟大家分享一下新项目的一些心得。

监听网络变化在开发中是经常用到的,例如我们断网有一些友好的提示,或者根据不同的网络更改一些加载策略,例如wifi看视频,非wifi则会有一个提示,还有极个别更恶心的偷摸的在后台给你下各种安装包,是谁我就不一一列举了。

在5.0以前,我们都是广播BroadcastReceiver,注册跟网络变化相关的广播,然后判断是连接还是断开,这种做法非常方便,但是随着安卓的版本迭代,在权限上越来越谨慎,广播的方式就显得不太优雅。

打个比方,之前就是拿个大喇叭,在大街上各种喊,就好像逛地摊,各种商品的吆喝声混在一起,需要你自己去分辨哪些是你想要的信息,而且又显得很不安全,万一卖的商品比较隐私呢,大家都是很低调的人。

所以在安卓5.0以上终于对网络的监听进行了优化,那就是通过Callback回调的方式,这种开发模式是不是很常用?例如监听下载进度,我只需要三个回调:下载成功,下载失败,下载的进度变化,这种回调方式针对性强,耦合性低,非常方便,和广播相比,就好像我们是一个订购了服务,需要的东西自动上门,very good。

废话铺垫了这么多,下面就是一个实战demo。

正文#

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        // 请注意这里会有一个版本适配bug,所以请在这里添加非空判断
        if (connectivityManager != null) {
            connectivityManager.requestNetwork(new NetworkRequest.Builder().build(), new ConnectivityManager.NetworkCallback() {

                /**
                 * 网络可用的回调
                 * */
                @Override
                public void onAvailable(Network network) {
                    super.onAvailable(network);
                    Log.e("lzp", "onAvailable");
                }

                /**
                 * 网络丢失的回调
                 * */
                @Override
                public void onLost(Network network) {
                    super.onLost(network);
                    Log.e("lzp", "onLost");
                }

                /**
                 * 当建立网络连接时,回调连接的属性
                 * */
                @Override
                public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
                    super.onLinkPropertiesChanged(network, linkProperties);
                    Log.e("lzp", "onLinkPropertiesChanged");
                }

                /**
                 *  按照官方的字面意思是,当我们的网络的某个能力发生了变化回调,那么也就是说可能会回调多次
                 *
                 *  之后在仔细的研究
                 * */
                @Override
                public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
                    super.onCapabilitiesChanged(network, networkCapabilities);
                    Log.e("lzp", "onCapabilitiesChanged");
                }

                /**
                 * 在网络失去连接的时候回调,但是如果是一个生硬的断开,他可能不回调
                 * */
                @Override
                public void onLosing(Network network, int maxMsToLive) {
                    super.onLosing(network, maxMsToLive);
                    Log.e("lzp", "onLosing");
                }

                /**
                 * 按照官方注释的解释,是指如果在超时时间内都没有找到可用的网络时进行回调
                 * */
                @Override
                public void onUnavailable() {
                    super.onUnavailable();
                    Log.e("lzp", "onUnavailable");
                }

            });
        }
    }
}

}

这就是今天的全部代码了,上面已经有了响应的注释,但是还是不够便于我们理解,接下来就仔细的研究一下:

1、首先我们打开app,此时网络是连接的状态:

image

一打开demo,我们立刻就得到了onAvailable的回调,意思就是网络目前可用,这一点比广播强多了,因为我们已启动还要单独处理一次,而通过回调的方式,可以立刻得到当前的状态。

2、然后我们手动关闭网络:

image

哎?没有onLosing的回调,只看到了onLost,说明我们手动关闭网络连接是一个很粗暴的行为,就像官方注释上写的,如果是一个生硬的断开,他可能不回调。

3、最后我们再次连接网络:

image

这次的回调就比较多了,首先是onAvailable,显示网络可用,然后是onCapabilitiesChanged,说此时网络的连接能力发生了第一次变化,估计是连接中把,再然后是onLinkPropertiesChanged,说明连接的属性已经发生了变化,此时应该获得了ip地址等信息,最后又回调了onCapabilitiesChanged,那么应该是网络进度到可用的状态。

总结#

我没有模拟出onLosing和onUnavailable的场景,至少说明他俩的出现的概率现在已经不高了,我们已经通过注释简单理解了他俩的场景,这里就不做深入研究了。

通过刚才的实验,我们得出了一下结论:

1、要想监听网络的连接和断开,应该在onAvailable和onLost中,他们一定会成对出现。

2、其他的几个回调使用场景会少一点,并且onCapabilitiesChanged会回调多次,所以使用它时我们要慎重,避免重复的操作,但是可以保证最后一次回调,网络的连接一定是连接成功的。

OK,从这个小小的变化,我们看到了安卓在慢慢变得更好,使用起来更简洁更优雅,这也加大了某些素质低的厂商想尽办法后台干点坏事的行为。

今天就到这里,有什么问题大家一起留言讨论~

补充#

1、记得申请权限:
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" />
尤其是WRITE_SETTINGS,这个需要手动申请,千万别忘了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,064评论 25 707
  • 你看,离别又见下雨天,你瞧,眼含的泪水强忍了回去。当然希望能够在一起奋斗,也期望生活的稳定,哪里都会有同样的梦,也...
    聂一一阅读 134评论 0 0
  • 好想再上一次大学 我一定不会浪费光阴。
    相相相柳阅读 126评论 0 0
  • 早晨起来终于打开了QQ,看到了师弟发来的长串消息。我想他终于意识到我要走了,通篇没有怎么考虑我的情绪,还是述说他对...
    陈汐留阅读 394评论 0 0
  • ade涵阅读 565评论 8 4