Android四大组件之 BroadCastReceive 使用总结

BroadCast的定义:

广播是一种订阅--通知 事件,广播接收者向Android系统 register (订阅广播),广播发送者向Adnroid系统 sendBroadCast(发送广播),然后Android 系统通知所有注册该广播的接收者,广播接收者收到自己注册的广播之后实现自己想做的事情(该事情一般不超过10s,否则应用会出现ANR)。

BroadCast的分类:

1.无序广播:也就是普通广播,只要注册了该action的广播接收者都能收到该广播,且没有先后顺序。

2.有序广播:广播接收者按照优先级高低依次接受该广播,并且优先接收的广播可以通过setResultExtras(Bundle)方法,将处理好的结果传送到下一个广播接收者那里。

3.粘性广播:发送广播调用的方法 sendStickyBroadcast(Intent),和sendBroadcast(Intent)不同。

粘性广播会一直保留在内存当中,直到有广播接收者注册该广播,该广播才算结束。不好解释,等会具体看例子。

BroadCase的使用:

一.普通广播:根据注册方式不同可以分为 静态注册广播和动态注册广播。

1.静态注册广播使用实例

AndroidManifest.xml 如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xjp.mybroadcast">

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--静态注册广播,此处需要添加广播的action-->
        <receiver android:name=".BroadCastReceive1">
            <intent-filter>
                <action android:name="com.xjp.mybroadcast.BroadCastReceive1"></action>
            </intent-filter>
        </receiver>
    </application>

</manifest>

2.广播接收者实现如下:

package com.xjp.mybroadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Description:静态广播接收器
 * User: xjp
 * Date: 2015/5/14
 * Time: 14:56
 */

public class BroadCastReceive1 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //TODO 接收到广播之后处理自己的事情
        String action = intent.getAction();
        String result = intent.getStringExtra("key");
        MyLog.d("the BroadCast action is " + action + "   the BroadCast receive result is " + result);
    }
}

3.广播发送者实现如下:

package com.xjp.mybroadcast;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

    private Button btnSend;

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

        btnSend = (Button) findViewById(R.id.button);
        btnSend.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                sendBraodCast();
                break;
        }
    }

    private void sendBraodCast() {

        /**
         * 申明静态广播的 action 行为
         */
        String action = "com.xjp.mybroadcast.BroadCastReceive1";
        Intent intent = new Intent(action);
        intent.putExtra("key", "静态广播测试");
        sendBroadcast(intent);
    }
}

打印结果如下:

4.静态注册广播特点:

1.注册广播在 AndroidManifest.xml中。

2.广播接收者需重新 继承 BroadcastReceiver 类来实现 onReceive()抽象方法。

3.应用退出无需 注销广播,因此导致:即使广播退出之后,如果有其他应用发送该action行为的广播,此应用还是能接收到该广播的,也就是还会打印上面的 结果。

二.动态广播:

示例

<pre name="code" class="java">package com.xjp.mybroadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

    private Button btnSend;

    private BroadCastReceive2 myReceive;

    private IntentFilter filter;

    private final static String ACTION = "com.xjp.mybroadcast.BroadCastReceive2";

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

        btnSend = (Button) findViewById(R.id.button);
        btnSend.setOnClickListener(this);

        myReceive = new BroadCastReceive2();
        filter = new IntentFilter();
        filter.addAction(ACTION);

    }

    @Override
    protected void onResume() {
        /**
         * 注册广播
         */

        LocalBroadcastManager.getInstance(this).registerReceiver(myReceive, filter);//官方建议使用

//        this.registerReceiver(myReceive, filter);

        super.onResume();
    }

    @Override
    protected void onPause() {
        /**
         * 注销广播
         */

        LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceive);//官方建议使用

//        this.unregisterReceiver(myReceive);

        super.onPause();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                sendBraodCast();
                break;
        }
    }

    private void sendBraodCast() {

        /**
         * 申明广播的 action 行为
         */
        Intent intent = new Intent(ACTION);
        intent.putExtra("key", "动态广播测试");

        /**
         * 官方提倡使用如下发送广播,原因是更快,更安全,不会导致内存泄漏
         */
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

//        this.sendBroadcast(intent);
    }

    /**
     * 内部类实现广播接收器
     */
    private class BroadCastReceive2 extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //TODO 接收到广播之后处理自己的事情
            String action = intent.getAction();
            String result = intent.getStringExtra("key");
            MyLog.d("the BroadCast action is " + action + "   the BroadCast receive result is " + result);
        }
    }
}

打印结果如下:

动态广播特点:

1.在代码中调用registerReceiver()方法 注册广播。

2.广播接收者需重新 继承 BroadcastReceiver
类实现内部类。

3.动态广播在应用退出时需要 调用unregisterReceiver()方法来注销广播。如果应用退出时没有注销广播,会报如下错误:

因此,我们通常的做法是:在 onResume()中注册广播,在onPause中注销广播。

4.当广播注销之后就接收不到任何系统发送的广播了。

三.有序广播:

示例:

<pre name="code" class="java">package com.xjp.mybroadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

    private Button btnSend;

    private BroadCastReceive2 myReceive;

    private BroadCastReceive3 myReceive3;

    private IntentFilter filter;

    private IntentFilter filter3;

    private final static String ACTION = "com.xjp.mybroadcast.BroadCastReceive2";

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

        btnSend = (Button) findViewById(R.id.button);
        btnSend.setOnClickListener(this);

        myReceive = new BroadCastReceive2();
        filter = new IntentFilter();
        filter.addAction(ACTION);
        filter.setPriority(2);//设置广播的优先级, -1000~1000 ,数字越大,优先级越高。

        myReceive3 = new BroadCastReceive3();
        filter3 = new IntentFilter();
        filter3.addAction(ACTION);
        filter3.setPriority(1);

    }

    @Override
    protected void onResume() {
        /**
         * 注册广播
         */
        registerReceiver(myReceive, filter);
        registerReceiver(myReceive3, filter3);

        super.onResume();
    }

    @Override
    protected void onPause() {
        /**
         * 注销广播
         */

        unregisterReceiver(myReceive);
        unregisterReceiver(myReceive3);

        super.onPause();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                sendBraodCast();
                break;
        }
    }

    private void sendBraodCast() {

        /**
         * 申明广播的 action 行为
         */
        Intent intent = new Intent(ACTION);
        intent.putExtra("key", "有序广播测试");

        this.sendOrderedBroadcast(intent, null);
    }

    /**
     * 内部类实现广播接收器
     */
    private class BroadCastReceive2 extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //TODO 接收到广播之后处理自己的事情
            String action = intent.getAction();
            String result = intent.getStringExtra("key");
            MyLog.d("the BroadCast action is " + action + "   the BroadCast receive result is " + result);

            Bundle bundle = new Bundle();
            bundle.putString("key", "有序广播处理之后" + "\n" + "再次发送给下一个广播接收者");
            intent.putExtra("bundle", bundle);
            setResultExtras(bundle);
            //切断广播,不再让此广播继续往下发送。
            //  abortBroadcast();
        }
    }

    /**
     * 内部类实现广播接收器
     */
    private class BroadCastReceive3 extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //TODO 接收到广播之后处理自己的事情
            String action = intent.getAction();
            //要不要接受上一个广播接收器receiver2传来的的数据
            Bundle bundle = getResultExtras(true);
            MyLog.d("the BroadCast action is " + action + "   the BroadCast receive result is " + bundle.getString("key"));
        }
    }
}

有序广播特点:

1.所有广播接收者的action是一致的,发送有序广播调用 sendOrderedBroadcast()方法。

2.有序广播的接收者需要调用setPriority()方法设置广播接收者的优先级。数字越大,优先接受广播。

3.有序广播如果需要终止 广播继续往下发送,可以调用 abortBroadcast()方法切断广播。

4.先接收广播者可以将自己的处理结果通过setResultExtras()方法继续传递给下一个广播接收者。

5.后接收者可以调用 getResultExtras(true)来自己决定是否接收上一个广播传递过来的数据。

四.粘性广播:

示例  需要在 AndroidManifest.xml中添加 权限

<uses-permission android:name="android.permission.BROADCAST_STICKY"></uses-permission>

发送广播的Activity

package com.xjp.mybroadcast;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;

/**
 * 发送广播的Activity
 */
public class MainActivity extends ActionBarActivity implements View.OnClickListener {

    private Button btnSend;

    private final static String ACTION = "com.xjp.mybroadcast.BroadCastReceive1";
    private final static String ACTION1 = "com.xjp.mybroadcast.BroadCastReceive2";

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

        btnSend = (Button) findViewById(R.id.button);
        btnSend.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                sendBraodCast();
                break;
        }
    }

    private void sendBraodCast() {

        /**
         * 申明广播的 action 行为
         */
        Intent intent = new Intent(ACTION);
        intent.putExtra("key", "普通广播测试");
        sendBroadcast(intent);

        Intent intent1 = new Intent(ACTION1);
        intent1.putExtra("key", "粘性广播测试");
        sendStickyBroadcast(intent1);
        startActivity(new Intent(this, RecevieActivity.class));
    }
}

接受广播的Activity

package com.xjp.mybroadcast;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

/**
 * Description:接受广播的Activity
 * User: xjp
 * Date: 2015/5/14
 * Time: 17:03
 */

public class RecevieActivity extends Activity {

    private final static String ACTION1 = "com.xjp.mybroadcast.BroadCastReceive1";
    private final static String ACTION2 = "com.xjp.mybroadcast.BroadCastReceive2";

    private Receive receive;

    private IntentFilter filter1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        receive = new Receive();

        filter1 = new IntentFilter();
        filter1.addAction(ACTION1);
        filter1.addAction(ACTION2);

    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(receive, filter1);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receive);
    }

    private class Receive extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            String result = intent.getStringExtra("key");
            MyLog.d("the BroadCast action is " + action + "   the BroadCast receive result is " + result);
        }
    }
}

打印结果如下:

从结果来看,只有粘性广播才能接收到广播信息。

粘性广播特点:

1.需要在AndroidManifest.xml中添加权限

<uses-permission android:name="android.permission.BROADCAST_STICKY"></uses-permission>

2.粘性广播发送除了调用方法不同sendStickyBroadcast(intent1),其他都一样。

3.一般广播都是先注册广播,才能接收到广播,而粘性广播可以做到先发送广播,哪里需要接收该广播就哪里注册,可以后注册广播拿到广播的结果。这就是 普通广播和粘性广播的区别。从示例中也看出了普通广播在跳转到ReceiveActivity中是接受不到广播发送者发出的广播的,只有粘性广播才能接收到。

有人会奇怪,平时也没看到哪里使用粘性广播??其实我也是看到Android 系统中 监测电池电量部分发现的。贴上代码如下:

// Register for the battery changed event
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);

/ Intent is sticky so using null as receiver works fine
// return value contains the status
Intent batteryStatus = this.registerReceiver(null, filter);

// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING
  || status == BatteryManager.BATTERY_STATUS_FULL;

boolean isFull = status == BatteryManager.BATTERY_STATUS_FULL;

// How are we charging?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 

广播的生命周期:

当广播接收者接收到广播调用完onReceive()方法之后,广播的生命周期就结束了。

因此广播接收器不能执行超过10s耗时任务,也不能在onReceive()方法中创建Thread 来执行耗时任务,你可以开启一个Service来执行后台耗时任务,具体可以参考Android 四大组件之Service 的生命周期和使用

广播的大概原理:

广播是怎么发送的?又是怎么接收的?

我们知道,只有先注册了某个广播之后,广播接收者才能收到该广播。广播注册的一个行为是将自己感兴趣的IntentFilter注册到Android系统的AMS(ActivityManagerService)中,里面保存了一个IntentFilter列表。广播发送者将自己的IntentFilter 的action行为发送到AMS中,然后遍历AMS中的IntentFilter列表,看谁订阅了该广播,然后将消息遍历发送到注册了相应IntentFilter的Activity或者Service中-----也就是会调用抽象方法onReceive()方法。其中AMS起到了中间桥梁作用。

系统广播:

Android系统中有很多系统广播,比如:

Event Description
Intent.ACTION_BOOT_COMPLETED Boot completed. Requires the android.permission.RECEIVE_BOOT_COMPLETEDpermission.
Intent.ACTION_POWER_CONNECTED Power got connected to the device.
Intent.ACTION_POWER_DISCONNECTED Power got disconnected to the device.
Intent.ACTION_BATTERY_LOW Triggered on low battery. Typically used to reduce activities in your app which consume power.
Intent.ACTION_BATTERY_OKAY Battery status good again.

系统广播具体怎么用?网络上一搜一大把,这里就不讲了。和我们写的广播使用都差不多。

时间: 2024-10-11 05:25:56

Android四大组件之 BroadCastReceive 使用总结的相关文章

Android 四大组件 详解

[置顶] Android四大组件详解 分类: Android四大组件2013-02-09 16:23 19411人阅读 评论(13) 收藏 举报 Android开发 注:本文主要来自网易的一个博主的文章,经过阅读,总结,故留下文章在此 Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity : 应用程序中,一个

Android四大组件之BroadcastReceiver详细解析

什么是BroadcastReceiver? BroadcastReceiver作为Android四大组件之一,在实际开发中也发挥着重要的作用,广播机制在Android程序通信中至关重要,广播其实与我们现实生活中的电台很相似,电台在某个频道上发送它的内容,那么只要有在收听这个频道的人都会收到这些内容.在Android中,广播也同样分为两个角色:广播发送者.广播接收者. BroadcastReceiver的应用场景 1.在一个应用中,我们的Activity与Service的通信就需要用到广播来作为中

Android四大组件--Activity详解

Android四大组件--Activity详解 分类: android android应用android开发 本文的主要内容包括1.activity的建立.配置和使用:2.activity的跳转和传值:3.startActivityForResult:4.activity的生命周期. 1.activity的建立.配置和使用 Activity是一个应用中的组件,它为用户提供一个可视的界面,方便用户操作,比如说拔打电话.照相.发邮件或者是浏览地图等.每个activity会提供一个可视的窗口,一般情况

android四大组件

Activity 为应用提供了可视化用户界面,与用户进行交互 启动模式 standard singleTop singleTask singleInstance ContentProvider内容提供者 共享数据,为跨应用的数据交换提供了一个标准 insert update delete query ContentResovler uri BroadcastReceiver广播接收者 用于接收程序(包括用户开发的程序和系统内建程序)所发出的broadcastReceiver 耗电量 开机启动 窃

Android四大组件及其应用--&gt;

android四大组件分别为:activity/service/content provider/broadcast receiver; 1.activity--> (1)一个Activity通常就是一个单独的屏幕(窗口). (2)Activity之间通过Intent进行通信. (3)android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity. 2.service--> (1)service用于在后台完成

android四大组件之Activity - (1)从源码中理解并巧用onWindowFocusChanged(boolean hasFocus)

这里开始到后面,想趁着有时间,将Android四大组件和一些系统组件做一些总结和记录.由于网上已经有很多写的很好并且总结也全面的文章.小弟我也囊中羞涩不敢献丑,就记录一些自己觉得重要的有用的知识点,顺便大家一起学习讨论啥的也好 Activity作为四大组件之一,对于整个Android开发有多重要就无需赘言了.关于它的生命周期,这里借用下官网的图,便一目了然: 那么它的生命周期和我们所说的onWindowFocusChanged(boolean hasFocus)方法有何关系? Activity生

android四大组件学习总结以及各个组件示例(1)

android四大组件分别为activity.service.content provider.broadcast receiver. 一.android四大组件详解 1.activity (1)一个Activity通常就是一个单独的屏幕(窗口). (2)Activity之间通过Intent进行通信. (3)android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity. (4)Activity生命周期>什么是

android四大组件--ContentProvider详解

一.相关ContentProvider概念解析: 1.ContentProvider简介 在Android官方指出的Android的数据存储方式总共有五种,分别是:Shared Preferences.网络存储.文件存储.外储存储.SQLite.但是我们知道一般这些存储都只是在单独的一个应用程序之中达到一个数据的共享,有时候我们需要操作其他应用程序的一些数据,例如我们需要操作系统里的媒体库.通讯录等,这时我们就可能通过ContentProvider来满足我们的需求了. 2.为什么要选择Conte

Android四大组件——Service

Service相关链接 Service初涉 Service进阶 Service精通 Service是Android系统中的一种组件,它跟Activity的级别差不多,但是它不能自己运行,只能后台运行,并且可以和其他组件进行交互.Service是没有界面的长生命周期的代码.Service是一种程序,它可以运行很长时间,但是它却没有用户界面.这么说有点枯燥,来看个例子,打开一个音乐播放器的程序,这个时候若想上网了,那么,我们打开Android浏览器,这个时候虽然我们已经进入了浏览器程序,但是,歌曲播