Android广播的学习

一、广播机制简介

1.Android中每个应用都可以对自己感兴趣的广播进行注册,监听。这些广播可以是系统的,也可以来自其他程序。

2.广播的类型:

  • 有序广播 : 是一种同步的广播,在广播发出后,同一时刻只有一个广播接收器可以收到广播,并且等待这个接收器,处理完成逻辑后,广播才会继续。所以这样广播接收器就有了优先级的划分,优先级高的自然能够首先获取广播信息 。优先级别的设置可以通过属性
<intent-filter android:priority="1000">
     <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
  • 标准广播 : 是一种完全异步的广播,在广播发出后,所有的广播接收几乎 可以同时获取到广播的信息,他们之间没有优先级别之分。

二、接收系统广播

Android中内置了很多系统级别的广播,我们可以在应用中通过监听这些广播来得到系统的信息。例如获取手机开机信息 ,获取手机网络信息等。其中我们需要在应用中注册自己的广播接收器,注册广播接收有两种方法

1.动态注册:通过代码在适当的位置进行广播接收器的注册,以及广播接收的注销注册。首先创建IntentFilter实例,并且设置其Action ,因为系统的每个广播发出都会带有action值。例如设备的网络发生变化的时候就会发出一条action值为 :”android.net.conn.CONNECTIVITY_CHANGE” 的广播。接着就是通过 registerReceiver(broadcastReceiver,filter)来注册广播接收器

  IntentFilter filter = new IntentFilter( );
  filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
  netWorkChangeReceiver = new NetWorkChangeReceiver() ;
  registerReceiver(netWorkChangeReceiver ,filter) ;
  Log.i("onCreate","注册广播接收器");
  unregisterReceiver(netWorkChangeReceiver);

动态注册广播可以自由地控制注册与注销,在灵活方面有很大的优势,但是它存在一个缺点,就是必须在程序启动后才能接收到广播。

2.静态注册:解决了动态注册的缺点,可以在程序安装的时候就完成注册,并且进行监听广播。首先创建 继承 BroadcastReceiver的实例 ,并且重写其中 onReceive() 方法 (注意在onReceive()方法中不能做过多耗时的操作) 。接着需要我们在AndroidManifest.xml中进行注册该广播接收器。具体代码如下:

public class MyReceiver extends BroadcastReceiver {
    private static final String PARAMES = "parames" ;
    public MyReceiver() {
        Log.i("BroadcastDemo ","myReceiver() ");
    }

    /**
     * 发送自定义 ,标准广播
     * @param context
     * @param parames
     */
    public static void sendBroadcast(Context context,String parames){
        Intent intent = new Intent("com.example.chf.broadcast_test") ;
        intent.putExtra(PARAMES ,parames) ;
        context.sendBroadcast(intent);
    }

    /**
     * 发送本地广播
     * 本地广播接收器,只能通过动态注册,因为本地广播是在程序启动之后才会
     * 去接收的
     * @param context
     * @param parames
     */
    public static void sendLocalBroadcast(Context context ,String parames){
        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context) ;
        //动态注册 本地广播接收器
        IntentFilter filter = new IntentFilter("com.example.chf.broadcast_test") ;
        MyReceiver myReceiver = new MyReceiver() ;
        localBroadcastManager.registerReceiver(myReceiver,filter);

        Intent intent = new Intent("com.example.chf.broadcast_test") ;
        intent.putExtra(PARAMES ,parames) ;
        localBroadcastManager.sendBroadcast(intent);
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent != null ){
            String parames = intent.getStringExtra(PARAMES) ;
            Toast.makeText(context,parames,Toast.LENGTH_SHORT).show();
            Log.i("接收广播信息",parames) ;
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.chf.thefirstlinecodeofandroid">
        .....
        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true"
            >
            <intent-filter android:priority="100">
                <action android:name="com.example.chf.broadcast_test"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

AndroidManifest.xml中属性设置 android:enable 以及android:exported的作用。

* android:enabled =”true” : 在程序安装后系统就会自动实例化广播接收器

* android:enabled =”false”: 程序安装后系统不会自动实例化广播接收器。

* android:exported =”true’ 允许广播接收器接收来自外部应用程序的广播

* android:exported =”false” 不允许广播接收器接收来自外部的应用程序的广播

参看http://developer.android.com/intl/zh-cn/guide/topics/manifest/receiver-element.html

发现了一个有趣的问题:当我创建一个获取网络状态的广播接收器的时候,并且把该广播接收器设置为静态注册,但是程序退出后,无论如何改变当前的网络状态都无法获取到广播信息。但是如果是自定义的广播接收器,并且进行了静态注册,即使程序处于退出的状态,也还是可以获取到自定义的广播信息。

主要原因:

Android 3.1开始系统在Intent与广播相关中为每一个Intent设置了 flag参数 ,分别是:

* FLAG_INCLUDE_STOPPED_PACKAGES (包含已经停止的包)

* FLAG_EXCLUDE_STOPPED_PACKAGES(不包含已经停止的包)

自Android3.1系统开始,系统本身会增加多所有的app当前是否处于运行状态的跟踪。在发送广播的时候,不管是什么广播类型,系统默认为其设置的flag值为 FLAG_EXCLUDE_STOPPED_PACKAGES ,导致即使是静态注册的广播接收器,如果app处于进程退出的状态,将不能收到广播

参看http://developer.android.com/about/versions/android-3.1.html#launchcontrols

对于自定义的广播,我们可以通过设置Intent的Flag值为 FLAG_INCLUDE_STOPPED_PACKAGES,使得静态注册的广播接收器,即使在App退出的情况下,也可以接收广播,并且会启动进程,但是此时的广播接收器会重新创建。

三、发送自定义广播

1.发送标准广播

Intent intent = new Intent("com.example.chf.broadcast_test") ;
intent.putExtra(PARAMES ,parames) ;
context.sendBroadcast(intent);

2.发送有序广播

通过 sendOrderedBroadcast(Intent intent ,String receiverPermission)发送有序广播。广播接收器 android:priority=”” 属性值越大接收广播的优先级越高,优先级较低的广播接收器只能等待优先级高的处理完逻辑后才能接收广播。但是优先级高的广播接收器,可以通过 abortBroadcast() 方法截断广播这样接下来的广播接收器就不可以接收到信息。同时优先级高的也可以通过 setResultData() 等方法 重新设置广播内容,这样在接下来的广播接收器通过 getResultData() 将会获取不一样的信息

public class MyReceiver extends BroadcastReceiver {
    private static final String PARAMES = "parames" ;
    public MyReceiver() {
        Log.i("BroadcastDemo ","myReceiver() ");
    }
    ......
    /**
     * 发送有序广播
     * @param context
     * @param parames
     */
    public static void sendOrderedBroadcast(Context context ,String parames){
        Intent intent = new Intent("com.example.chf.broadcast_test") ;
        intent.putExtra(PARAMES ,parames) ;
        context.sendOrderedBroadcast(intent,null);

    }
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent != null ){
            String parames = intent.getStringExtra(PARAMES) ;
            Toast.makeText(context,parames,Toast.LENGTH_SHORT).show();
            Log.i("接收广播信息","MyReceiver"+parames) ;
            //abortBroadcast();
            setResultData("从myReceiver()中修改后发出广播");
        }
    }
}
public class SecondReceiver extends BroadcastReceiver {
    public SecondReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        String parames = getResultData() ;
        Log.i("接收广播信息","SecondReceiver"+parames) ;
    }
}

配置AndroidManifest.xml ,并且设置属性优先级

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.chf.thefirstlinecodeofandroid">
        ......
        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.example.chf.broadcast_test" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".SecondReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="90">
                <action android:name="com.example.chf.broadcast_test" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

测试结果就是

四、使用本地广播

通过获取LocalBroadcastManager ,通过其发送 sendBroadcast(intent)的方式发送本地广播,并且本地广播只允许动态注册。

本地广播优势:

* 1.不必担心本应用发送的广播信息会被其他应用所获取,保证了数据的安全性

* 2.其他应用不可能随意发送广播,使得应用本地广播接收器接收,所以你不必担心它们会被利用

* 3.比系统发送的全局广播更见高效

        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context) ;
        //动态注册 本地广播接收器
        IntentFilter filter = new IntentFilter("com.example.chf.broadcast_test") ;
        MyReceiver myReceiver = new MyReceiver() ;
        localBroadcastManager.registerReceiver(myReceiver,filter);

        Intent intent = new Intent("com.example.chf.broadcast_test") ;
        intent.putExtra(PARAMES ,parames) ;
        localBroadcastManager.sendBroadcast(intent);

注意动态广播只能是通过动态注册的方式 ,并且都要使用LoaclBroadcastManager来进行注册与发送。

Ps:小弟不才,文中难免会有些漏洞,仅作为笔记用途。如果哪里有严重错误欢迎大家留言,助我改进。同时大家也可以交个朋友。

时间: 2024-11-29 00:23:16

Android广播的学习的相关文章

Android广播机制的深入学习

部分内容转载自http://www.cnblogs.com/lwbqqyumidi/p/4168017.html 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间): 2.同一app内部的不同组件之间的消息通信(单个进程): 3.同一app具有多个进程的不同组

Android(java)学习笔记172:Android广播机制

Android广播机制 android系统中有各式各样的广播,各种广播在Android系统中运行,当"系统/应用"程序运行时便会向Android注册各种广播.Android接收到广播后判断哪种广播需要哪种事件,然后向不同需要事件的应用程序注册事件. 不同的广播可能处理不同的事件,也可能处理相同的广播事件,这时候就需要Android系统的筛选.例如在一个经典的电话黑名单应用程序中,首相通过将黑名单号码保存在数据库里面,当来电的时候,我们接收的来电广播并将黑名单号码与数据库中某个数据做匹配

Android文档学习01_Android基础

一旦安装到了一个设备,每个应用生存在它自己的安全沙箱 系统给每个应用分配一个独立的Linux用户ID(这个ID只由系统使用并且对应用来说是不可知的) Android系统实现了最小特权原则.默认,每个应用仅仅访问需要工作的组件,并不多做其他的事.这样创建了一个非常安全的环境,应用不能访问系统没有授权的其他部分 有可能安排两个应用共用一个linux系统ID,在那种情况下,它们能互相访问相互的数据.为了节约系统资源,拥用相同用户ID的应用,可能也被安排运行在同一个Linux进程中并共享相同的VM(应用

Xamarin.Android广播接收器与绑定服务

一.前言 学习了前面的活动与服务后,你会发现服务对于活动而言似乎就是透明的,相反活动对于服务也是透明的,所以我们还需要一中机制能够将服务和活动之间架起一座桥梁,通过本节的学习,你将会学到广播与绑定服务,这两种方式恰恰是解决上面问题的关键. 二.简单的广播接收器 实现一个最简单的广播接收器需要继承BroadcastReceiver类,并且还要实现OnReceive方法,我们可以在项目中新建一个MainReceiver类,然后写入如下代码: 1 public class MainReceiver :

我的Android之旅——学习、项目、心态

本文作者: 伯乐在线 - 唐韧 .未经许可,禁止转载!欢迎分享原创到伯乐头条. 来源:唐韧 学习Android也一年多了,项目做了五六个,有大有小,有难有易.一直以来都没有好好总结过,今天周六休息,就写下这一年多从事Android以来的一些感想和小经验.涉及学习.项目和一些个人感受. 1.学习篇 我是从11年5月份开始接触并学习Android的,在那之前有过一年的J2EE的经验,做过三个J2EE的项目,从08年开始接触Java,所以到去年学习Android时,开发语言上我还是比较熟悉的,这也成了

Android FM模块学习之四源码解析(二)

上一章我们了解了FM主activity:FMRadio.java,若没查看的,请打开链接Android FM模块学习之四源码解析(一) 查看fmradio.java源码注释.接下来我们来看看FM重要的一个类:FMRadioService.java 由上一章我们已经知道,打开FM时,在OnStart函数中会bindToService来开启服务, public boolean bindToService(Context context, ServiceConnection callback) { L

Android广播机制:Broadcast

转载:Android总结篇系列:Android广播机制 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间): 2.同一app内部的不同组件之间的消息通信(单个进程): 3.同一app具有多个进程的不同组件之间的消息通信: 4.不同app之间的组件之间消息通信:

基于 Android NDK 的学习之旅----- C调用Java

http://www.cnblogs.com/luxiaofeng54/archive/2011/08/17/2142000.html 基于 Android NDK 的学习之旅----- C调用Java许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态方法. 1.主要流程 1.  新建一个测试类TestProvider.java a)       

Android广播机制(转)

1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间): 2.同一app内部的不同组件之间的消息通信(单个进程): 3.同一app具有多个进程的不同组件之间的消息通信: 4.不同app之间的组件之间消息通信: 5.Android系统在特定情况下与App之间的消息通