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;
判断是否是有序广播;