zoukankan      html  css  js  c++  java
  • 广播机制

          在计算机网络里,假如某个网络的IP地址是192.168.0.XXX,子网掩码是255.255.255.0,那么这个网络的广播地址就是192.168.0.255,广播数据包会被发送到同意网络上的所有端口,这样在该网络中的每台主机都会收到这条广播。Android也引入了一套类似的广播消息体制。

          Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样程序只会接收到自己关心的广播内容,这些广播可能来自于系统,也可能来自于其它应用程序。Android提供了一套完整的API,允许程序自由地发送和接收广播。Android中的广播可以分为两类,标准广播和有序广播。

    标准广播

         标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有先后顺序可言。这种广播的效率比较高,但同时也意味着它是无法被截断的。其工作流程如下:

        

    有序广播

         有序广播则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够接收到这条广播消息,当这个广播接收器中的逻辑执行完毕之后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的接收器可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的接收器就无法接收到广播消息了。其工作流程如下:

       

    接收系统的广播

          Android内置了很多系统级别的广播,可以在应用程序中通过监听这些广播来得到各种系统的状态信息。比如手机开机完成之后会发出一条广播,电池的电量发生变化会发生一条广播,时间或时区发生改变也会发出一条广播。如果想要接收到这些广播,就需要使用广播接收器。

        广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应的逻辑。注册广播的方式一般有两种,在代码中注册和在AndroidMainfest.xml中注册,前者称为动态注册,后者称为静态注册。建立广播接收器只需要新建一个继承自BroadcastReceiver的类,并重写onReceive()方法就行了。这样当广播到达时,onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。

        下面就是一个监听网络变化的程序,借此学习一下广播接收器的基本用法。

        

             每当网络发生变化,上面的程序就会显示一条信息。为IntentFilter添加一个android.net.com.CONNECTIVITY_CHANGE的广播,因为当网络发生变化时,系统就会发出一个值为android.net.com.CONNECTIVITY_CHANGE的广播,也就是广播接收器想要监听什么广播,就在里面添加相应的action就行了。最后一定要记得,动态注册的广播接收器一定要取消注册才行。

           不过只是提醒网络发生了变化还是不够人性化,最好是能告诉用户当前有网络还是没有网络,因此还需要对代码进行优化,修改NetworkChangeReceiver中的代码如下:

        

                 在onReceive()方法中,首先通过getSystemService()方法得到了ConnectivityManager的实例,这是一个系统的服务类,专门用于管理网络连接的,然后调用它的getActiveNetworkInfo()方法可以得到NetworkInfo的实例,接着调用NetworkInfo的isAvailable()方法就可以判断出是否有网络了。

         另外,Android系统为了保证应用程序的安全性做了规定,如果程序需要访问一些系统的关键性信息,必须在配置文件中声明权限才可以,否则程序会直接崩溃,比如上面的程序,在AndroidMainfest.xml文件里加入权限,如下:

    访问http://developer.android.com/reference/android/Mainfest.permission.html可以查看Android系统所有可声明的权限。

    静态注册实现开机启动

           动态注册的广播接收器可以自由地控制注册和注销,在灵活性上有很大的优势,但是存在一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。这里准备让程序接收一条开机广播,当收到这条广播时就可以在onReceive()方法里执行相应的逻辑,从而实现开机启动的功能,新建一个BootCompleteReceiver类,继承自BroadcastReceiver,代码如下:

          

    然后修改AndroidMainfest.xml文件,如下:

          到目前为止,在广播接收器的onReceive()方法中都只是简单地使用Toast提示了一段文本内容,当真正使用的时候可以在里面写上合适的逻辑,但是不要在onReceive()方法中添加过多的逻辑或者进行耗时的操作,因为在广播接收器中是不允许开启线程的,当onReceive()方法运行了较长的时间而没有结束时,程序会报错。因此,广播接收器更多的是扮演一种打开程序其它组件的角色,比如,创建一条状态栏通知,或者是启动一个服务等。

  • 相关阅读:
    阻塞队列整理
    List与Map整理
    2、Redis中的链表
    【观点】从曾成杰案看民间金融的高风险与银行缺失的机制创新
    林权抵押贷款政策出台 将实现林业资源变资本
    从《男生传递微笑给女生的故事》想到的流程梳理与优化
    落实制度靠流程<摘自平安50万人的执行力>
    vue踩坑- 报错npm ERR! cb() never called!
    vue踩坑-This dependency was not found
    vue踩坑- 报错npm ERR! cb() never called!
  • 原文地址:https://www.cnblogs.com/hujingwei/p/5111130.html
Copyright © 2011-2022 走看看