一、BroadcastReceiver简介:
BroadcastReceiver是Android四大组件之一,使用时必须进行注册;
2、、什么是广播?既然有广播接收者,那肯定会有广播了。广播是一种广泛运用的在应用程序之间以及应用程序内部传输信息的机制。
Android中的广播主要分为两种:
1)、 标准广播(普通广播):是一种完全异步执行的广播,即就是在广播被发出去之后,所有的广播接收者几乎在同一时间接收该广播,没有任何先后顺序。
发送方式:Context.sendBroadcast()
优点:完全异步,消息传递效率很高
2)、有序广播:是一种完全同步的广播,即就是有序广播被发出去后,同一时刻只会有一个接受者可以接收到这条广播,当这个广播接受者完成了自己的逻辑后,广播才会继续传递。
发送方式:Context.sendOrderedBroadcast()
优点:可以根据广播接受者的优先级顺序依次发送,优先级较高的广播接收者可以处理完广播后再传给一下广播接收者,也可以根据需要调用abortBroadcast()终止广播传播。
缺点:传递的效率低。
广播的三要素:
广播 发送广播
广播接收者 接收广播
Intent意图 用于保存广播的相关信息
二、BroadcastReceiver的工作流程
1、 发送:需要在发送广播的地方,把过滤的信息和发送的信息放入到Intent对象中,然后通过调用sendBroadcast()/sendOrderBroadcast()方法,发送这条信息。
2、接收:广播发送后,已经注册的广播接收者会监测自己的过滤器,看看是否符合条件,符合,则处理;否则,则不处理。
三、BroadcastReceiver的作用:
1、监听系统的或自己的广播,并做出相应的处理:
2、后台操作在执行耗时操作后,可以通过广播接收者,将数据返回
四、BroadcastReceiver的注册:
1、静态注册:
在清单文件中通过<receiver/>节点注册。
①、需要通过name属性指定当前注册的是哪个广播接收者(类),需要指定全类名(包名+类名或者.类名);
②、在<receiver/>节点中添加过滤器即添加<intent-filter>,并指定action
2、动态注册:
通过Java代码注册,注册后需要手动取消注册
API建议:onResume()生命周期方法中注册,在onPause()方法中取消注册,但是在实际开发中,一般在onCreate()方法中注册,onDestroy()方法中取消注册
注册:
BroadcastReceiver,IntentFilter);===》定义BroadcastReceiver子类对象、IntentFilter对象(指定action);并將BroadcastReceiver对象提成全局(取消时要使用)
取消注册:
unregisterReceiver(BroadcastReceiver);
2、两种注册方式的比较:
静态注册:属于全局注册,程序安装之后,就一直存在,知道程序卸载;
动态注册一般用于程序内部的监听,只有启动该应用,才会生效
3、系统广播中必须静态注册的广播:
用户拨打电话的监听、用户接入电话的监听、用户接收到电话的监听
必须动态注册的广播:
电池电量的改变、网络状态的检测
五、发送广播和接收广播:
1、发送广播:
step1:得到Intent对象;
Intent intent=new Intent();
step2:设置频道(添加action,必须和BroadcastReceiver注册时指定的action一样才可以接收);
intent.setAction("com.qf.receiver");
step3:设置内容;
intent.putExtra(key,value);
step4:发送广播;
无须广播: sendBroadcast(intent);
有序广播://意图对象 接收到该广播需要的权限,null:表示不需要任何权限
sendOrderedBroadcast(intent,null);
2、接收广播:
自定义类继承BroadcastReceiver时,必须重写onReceive()方法,当BroadcastReceiver接收广播时,调用此方法;
该方法有两个参数:Context :BroadcastReceiver运行的上下文对象, intentBroadcastReceiver接收到的意图对象,该对象中包含了信息,可通过该对象获取具体的信息,并执行相应的操作,注意:此方法运行在主线程中,不宜执行耗时操作;
3、简单代码:
public class MainActivity extends AppCompatActivity {
private My my;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
my = new My();
IntentFilter intentFilter=new IntentFilter("android.com.my");
registerReceiver(my,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(my);
}
//发送广播
public void send(View view) {
Intent intent=new Intent();
intent.setAction("android.com.my");
intent.putExtra("msg","天冷,加衣");
sendBroadcast(intent);
//意图对象 接收到该广播需要的权限,null:表示不需要任何权限
sendOrderedBroadcast(intent,null);
}
class My extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
Toast.makeText(MainActivity.this, "***"+intent.getStringExtra("msg"), Toast.LENGTH_SHORT).show();
}
}
}
}
六、内部广播接收者可以实现静态注册吗?如何实现?
内部广播接收者也可以实现静态注册,但是前提是继承于BroadcastReceiver的内部类必须是静态(static)的;
注册方式于外部类基本一样:
<receiver android:name=".MainActivity$MyBroadReceiver">
<intent-filter>
<action android:name="com.android.chat.chatlist"/>
</intent-filter>
</receiver>
七、广播安全
方式一:接收者
静态注册广播可以设置:android:exported="false"
<receiver
android:name=".AStaticReceiver"
android:enabled="true"
android:exported="false" <!--设置只能接收app内广播 -->
>
<intent-filter android:priority="100"><!--设置优先级-->
<action android:name="com.whoislcj.broadcastreceiver.staticreceiver" />
</intent-filter>
</receiver>
方式二:发送者
通过设置发送的广播只能app内接收
Intent intent = new Intent();
intent.setAction(ActionCodes.DYNAMICACTION);//设置Action
intent.setPackage(getPackageName());//设置包名使广播只能被包名的app内接收者接收
intent.putExtra("msg", "我是普通广播(动态注册)");//添加附加信息
sendBroadcast(intent);
方式三:通过LocalBroadcastManager方式
注册:
LocalBroadcastManager.getInstance(getInstance()).registerReceiver(receiver, filter);
解除注册:
LocalBroadcastManager.getInstance(getInstance()).unregisterReceiver(receiver);
发送:
LocalBroadcastManager.getInstance(getInstance()).sendBroadcastSync(intent);
问题:
1.什么是本地广播?
只能发送广播到程序的内部;
3.本地广播的注册方式?
必须动态注册
4.如何使用本地广播?
step1:获取本地广播管理者;
loaclManager=LocalBroadcastManager.getInstance(this);
step2:通过该对象动态注册广播即为本地广播;
loaclManager.registerReceiver(receiver,filter);
step3:在当前应用程序中发送广播与接收广播;
loaclManager.sendBroadcast(intent);
step4:通过本地广播管理者对象取消注册本地广播;
loaclManager.unregisterReceiver(receiver);
通过上述两种方式只能达到屏蔽外来广播以及广播只在app内传播,无法实现app之间安全发送广播
方式四:通过自定义权限:(App之间的广播安全)
自定义权限:
<permission android:name="com.whoislcj.broadcastreceiver.MySelfBroadcastReceiver" />
<uses-permission android:name="com.whoislcj.broadcastreceiver.MySelfBroadcastReceiver"/>
动态注册:
IntentFilter dynamicFilter = new IntentFilter();
dynamicFilter.addAction(ActionCodes.DYNAMICACTION);//添加动态广播的Action
dynamicFilter.setPriority(500);
//设置权限
registerReceiver(dynamicReceiver, dynamicFilter,ActionCodes.MYPERMISSION,null);
静态注册:
<receiver
android:name=".BStaticReceiver"
android:enabled="true"
android:exported="true"
<!--设置权限-->
android:permission="com.whoislcj.broadcastreceiver.MySelfBroadcastReceiver">
<intent-filter android:priority="500">
<action android:name="com.whoislcj.broadcastreceiver.staticreceiver" />
</intent-filter>
</receiver>
发送广播:
//普通广播
sendBroadcast(intent,ActionCodes.MYPERMISSION);
//有序广播 sendOrderedBroadcast(intent,ActionCodes.MYPERMISSION);
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
工作近两年了,到底收获了什么?
突然想写博客了,毕竟,曾经写了那么多的学习笔记(包括Android,包括Java后端),似乎都用不上了!有点莫名的伤感,从Android到后端,再到如今的web开发,如今,看到招聘要求上写着“有原生Android开发经验优先”,只能默默感叹一声。
打开好久没浏览过的自己的博客,突然发现了这篇被遗忘在草稿箱里的学习笔记,就像看到了很久之前的以为老朋友,想了想,还是发布吧,算是一个好的开端吧。
希望今后的自己,能记录下自己工作中遇到的问题,也算是留下了那么一丝丝痕迹了吧。