Android四大组件之广播总结

来源:互联网 发布:centos开启3306端口 编辑:程序博客网 时间:2024/06/18 02:58

Android四大组件之广播总结:

Android广播机制知识体系图

1.广播接收器的注册

  什么是广播接收器?广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应的逻辑。注册广播一般有两种,在代码中注册和在AndroidManifest.xml注册,其中前者也被称为动态注册,后者也被称为静态注册。

1.1 动态注册广播接收器

  如何创建一个广播接收器呢?其实就需要新建一个类,让它继承自BroadcastReceiver,并重写父类的onReceive()方法就行了。这样有广播到来时,onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。来个简单的例子来理解以下,如何监听网络变化呢?其实就是新建一个广播接收器去接收来自系统网络变化的广播即可,代码如下所示:

public class MainActivity extends AppCompatActivity{    private IntentFilter intentFilter;    private NetWorkChangeReceiver netWorkChangeReceiver;    @Override    protected void onCreate(Bundle savedInstanceState){        super.Oncreata(savedInstanceState);        setContentView(R.layout.activity_main);        intentFilter = new IntentFilter();        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");        networkChangeReceiver = new NetWorkChangeReceiver();        registerReceiver(networkChangeReceiver, intentFilter);//注册广播接收器    }    @Overrid    protected void onDestroy(){        super.onDestroy();        unregisterReceiver(networkChangeReceiver);//一定要记得取消广播接收器的注册    }      class NetworkChangeReceiver extends BroadcastReceiver{//广播接收器类        @Override        public void onReceiver(Context context,Intent intent){            //这里需要权限,需要在AndroidManifest.xml中进行网络访问权限申请:            //<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>            ConnectivityManager connectionManager = (ConnectivityManager)            getSystemService(Context.CONNECTIVITY_SERVICE);            NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();            if (networkInfo != null && networkInfo.isAvailable()) {                  //有网                  Toast.makeText(context, "network is available",Toast.LENGTH_SHORT).show();            } else {                  //无网                  Toast.makeText(context, "network is unavailable",                  Toast.LENGTH_SHORT).show();            }        }    }}

  动态注册广播接收器的优点以及缺点:动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。那么有没有广播能在程序未启动的情况下就能接收到广播呢?静态注册的广播接收器就可以做到。

2.2 静态注册广播接收器

  首先你要创建一个广播接收器类,实例代码如下:

public class BootCompleteReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();    }}

  代码非常简单,我们只是在onReceive()方法中使用Toast弹出一段信息提示信息。
另外,静态的广播接收器一定要在AndroidManifest.xml文件中注册才可以使用,AndroidManifest.xml文件中注册静态广播代码如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"       package="com.example.broadcasttest"       android:versionCode="1"       android:versionName="1.0" >       ……      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />      <application           android:allowBackup="true"           android:icon="@drawable/ic_launcher"           android:label="@string/app_name"           android:theme="@style/AppTheme" >           ……           <receiver                android:name=".BootCompleteReceiver" >               <intent-filter>                   <action android:name="android.intent.action.BOOT_COMPLETED" />               </intent-filter>           </receiver>      </application></manifest>

  可以看到,标签内出现了一个新的标签,所有静态的广播接收器都是在这里进行注册的。它的用法其实和标签非常相似,也是通过android:name来指定具体注册哪一个广播接收器,而enabled和exported属性则是根据我们刚才勾选的状态自动生成的,也可以自己添加,没有就自己添加嘛!

2.发送广播

  要想发送的广播有意义,你首先得确认你发送的广播有广播接收器进行接收并触发接收的逻辑处理,不然发送是毫无意义的。无论发送标准广播还是有序广播,都需要通过Intent来进行发送。

标准广播工作机制图

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

有序广播工作机制图

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

2.1 发送标准广播

Intent intent = new Intent("com.example.broadcasttest.My_BROADCAST");sendBroadcast(intent);

  标准广播的发送是很简单,但是有序广播呢,里面涉及到广播接收器的优先级,是否拦截等问题,下面来看看有序广播发送的问题:

2.2 发送有序广播

Intent intent = new Intent("com.example.broadcasttest.My_BROADCAST");sendOrderedBroadcast(intent,null);

  没错,发送有序广播要使用sendOrderedBroadcast()方法,此方法接收两个参数,第一个参数是Intent,第二个参数是一个与权限相关的字符串,这里传入null就可以了。那么要接收这条有序广播的广播接收器如何设置优先级呢?又如何去拦截这条有序广播呢?

  下图代码对广播接收器的优先级进行了设置,将广播接收器的优先级设置为100,优先级越大越能先接收到对应的有序广播。
这里写图片描述

  那么如何拦截有序广播呢?其实很简单,在广播接收器内执行abortBroadcast()方法即可对有序广播进行拦截,拦截后,后面的接收这条被拦截的广播对应的广播接收器将无法再收到这条广播。实例代码如下所示:

这里写图片描述

3.本地广播的使用

  Android引入一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本地应用程序发出的广播,这样所有的安全问题就都不存在了。
  本地广播的用法并不复杂,主要就是使用了一个LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法。实例代码如下:

这里写图片描述

这里写图片描述

这里写图片描述

最后盘点一下使用本地广播的几点优势:

  • 1.可以明确地知道正在发送的广播不会离开我们的应用程序,因此不必担心机密数据泄露。
  • 2.其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患。
  • 3.发送本地广播比发送系统全局广播会更加有效。

4.广播机制的底层原理

  弄懂广播机制的底层原理是一件非常困难的事儿,就连笔者自己都不敢说自己完全弄懂了,所以笔者自己总结的话就误人子弟了,毕竟今年是笔者Android开发的第二年,还没满2年呢,所以期待以后阅读Android源码,来给大家写一写Android庞大知识体系的底层实现原理,这里笔记就贴上一个分析Android广播底层原理不错的大神博客:

http://blog.csdn.net/windskier/article/details/7251742
原创粉丝点击