Android BroadcastReceiver 详解

BroadcastReceiver

位置:framework/base/core/java/android.content.BroadcastReceiver.java

意义:按照翻译字面理解,就是广播接收器,那么接收的就是消息,要接收消息,就必定要发送消息,就理解成现实中的广播一样。BroadcastReceiver 接收的是Broadcast(广播)中的 Intent (意图、意向),而广播 Intent的发送 方法则是 sendBroadcast(),sendOrderedBroadcast(),前者发送的是普通广播,后者发送的是有序广播。 

作用:对发送出来的广播进行过滤,接收并且响应。

机制:广播分为系统级的和用户级的,系统级的是指Android API 已经定义了的广播,我们只需要接收就可以,比如电量低广播、开机完成广播、来电广播、短信广播、耳机口接入耳机广播等等,后面我会给出一份所有系统级的广播列表。至于用户级的,就是用户自己定义的广播,

实现:

第一种方式:

package com.lsy.demo;

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

public class MyBroadcastReceiver extends BroadcastReceiver{
	
	private String action = "android.intent.action.ACTION_BATTERY_LOW";//电池电量低

	@Override
	public void onReceive(Context context, Intent intent) {
		
		if(intent.getAction().equals(action)){
			//你的操作,比如提醒充电
		}
	}

}

注册

<receiver
            android:name=".MyBroadcastReceiver"
            >
            <intent-filter>
                <action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </receiver>

第二种方式:

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){

		@Override
		public void onReceive(Context context, Intent intent) {
			//你的操作,比如重启设备后的一些操作
		}
	};

注册

<pre name="code" class="java">IntentFilter intentFilter = new IntentFilter( "android.intent.action.ACTION_REBOOT" );
registerReceiver(mBroadcastReceiver,intentFilter);

主要的区别体现在两种注册方式上,第一钟是常驻性的,也就是说退出应用之后,它依然存在,第二种则会跟随Activity或者是Service的生命周期创建消亡,所以一定要在记得在onDestory()中 unregisterReceiver(mBroadcastReceiver);

注:BroadcastReceiver的生命周期只有10s,所以,不要在onReceiver(Context,Intent)中做耗时操作,否则会报ANR错(Application Not Response)。

那么怎么做避免上面的问题:

通过发送 Intent 给Service ,由Service 来完成耗时操作,完成后再发送广播,这里不能自己单启子线程,因为BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的。

广播的类型和收发:

普通广播,完全是异步的,只要监听了该广播的接收器都能够接收到信息。

有序广播,是同步的,只会发送给优先级更高的接收器,优先级的数值从 -1000 到 1000,优先级可以在 Intent-Filter 中的 Priority 属性去设置。优先级高的广播可以终止广播的继续发送,同时也可以修改传播的信息的内容。

发送和接收:

普通广播:

Intent intent = new Intent( "com.tcl.luosiye " );
sendBroadcast(intent);

priority :这个是 AndroidManifest.xml 中 intent-filter 的参数。

< receiver android:name = ".MyBroadcastReceiver" >
       < intent-filter android:priority = "1000" >
              < action android:name = "com.tcl.luosiye" />
       </ intent-filter >
</ receiver >

有序广播:

sendOrderedBroadcast(intent, receiverPermission);
sendOrderedBroadcast(intent, receiverPermission, resultReceiver,
scheduler, initialCode, initialData, initialExtras)

意图,广播,所有匹配的这一意图将接收机接收广播。

receiverPermission 这是权限,一个接收器必须持以接收您的广播。如果为 null ,不经许可的要求。 
resultReceiver 您自己 BroadcastReceiver 来当作最后的广播接收器。 
调度自定义处理程序,用以安排 resultReceiver 回调 ; 如果为 null 将语境中的主线程举行。 
initialCode 一种结果代码的初始值。通常为 Activity.RESULT_OK 。这个值是 -1 ;为其他 int 型 也可以,如 0,1,2; 
initialData 一种结果数据的初始值。通常情况下为空 , 是 String 类型 ;
initialExtras 一种结果额外的初始值。通常情况下为空 , 是 Bundle;

1,  该广播的级别有级别之分,级别数值是在 -1000 到 1000 之间 , 值越大 , 优先级越高;

2,  同级别接收是先后是随机的,再到级别低的收到广播;

3,  同级别接收是先后是随机的,如果先接收到的把广播截断了,同级别的例外的接收者是无法收到该广播的。(abortBroadcast() )

4 ,能截断广播的继续传播,高级别的广播收到该广播后,可以决定把该钟广播是否截断掉。

5 ,实验现象,在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先

API 源码分析:

abortBroadcast ():

这个方法可以截获由 sendOrderedBroadcast () 发送来的 广播,让其它广播接收者无法收到这个广播。

clearAbortBroadcast ()

这个方法是针对上面的 abortBroadcast() 方法的,用于取消截获广播。这样它的下一级广播接收者就能够收到该广播了。

getAbortBroadcast ()

这个方法作用是:判断是否调用了 abortBroadcast (),如果先调用 abortBroadcast (),接着再调用getAbortBroadcast (),将返回 true; 如果在调用 abortBroadcast() 、 clearAbortBroadcast ()

getAbortBroadcast (),将返回 false;

public final boolean getDebugUnregister ()

Since: API Level 1

Return the last value given to setDebugUnregister(boolean) .

getResultCode ()

如果用下面四个方法发送得广播,返回码为: -1 ;

// sendBroadcast(intent);

// sendBroadcast(intent, receiverPermission);

// sendOrderedBroadcast(intent, receiverPermission);

// sendStickyBroadcast(intent);

如果用下面两个方法发送得广播,返回码为:根据你设置 initialCode 的数字是多少就是多少;

// sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

// initialCode, initialData, initialExtras)

// sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

// scheduler, initialCode, initialData, initialExtras)

getResultData ()

得到发送广播时设置的 initialData 的数据;

getResultExtras (boolean makeMap)

If true then a new empty Map will be made for you if the current Map is null; if false you should be prepared to receive a null Map.

得到由

sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

// initialCode, initialData, initialExtras) ;

// sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

// scheduler, initialCode, initialData, initialExtras)

中 initialExtras 传入的参数。

实验:我用上面两个方法发了 initialExtras (这个一个 Bundle )传入的参数时,只要不为空,那么 makeMap是否为 true 和 false 都能够得到数据。

isInitialStickyBroadcast ()

Returns true if the receiver is currently processing the initial value of a sticky broadcast — that is, the value that was last broadcast and is currently held in the sticky cache, so this is not directly the result of a broadcast right now.

如果广播接收者是目前处理的一个宿主的广播的初始值,将返回 true , – 也就是说,这个值是最后的广播出的值,目前正在举行的宿主缓存,所以这并不是直接导致了现在的广播。

实验:在第三个应用中调用这个方法,无论你用哪种方式发送广播,这个方法得到的总是 false ;在发送广播 的resultReceiver 广播接收者里面调用,得到的也是 false ;

isOrderedBroadcast ()

sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

  initialCode, initialData, initialExtras)

上面这个方法发送时,得到的是 true;

判断是否是有序广播;

    原文作者:dancing_with_wolf
    原文地址: https://blog.csdn.net/dancing_with_wolf/article/details/37907123
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞