Android 广播机制和过滤机制(BroadCast)_安卓基础

1 广播类型

     

静态注册:通过<receiver></receiver>的形式在AndroidManifest.xml中注册的广播;

动态注册:通过context. registerReceiver在程序中显示注册的广播;

       上面静态广播和动态广播比较明显的3个区别:

(1)静态广播在进程没有运行的时候,也可以收到,这时候会先启动进程,然后处理广播onReceive函数(静态广播可以拉起进程,但是目前很多厂商为了禁止应用自启动,对于广播拉起应用都有一些限制,被禁止自启动的应用AMS直接就把相应的静态注册接收者过滤掉了),动态广播因为是在程序中通过代码显示注册的,因此必须要在进程已经运行的时候才能收到广播。

(2)静态广播处理的时候每次都会创建一个新的广播接收器对象,但是动态广播一般都是同一个广播接收器对象。

(3)针对同样一个非order广播,所有动态注册接收者要先于所有的静态接收者先收到广播,同一个应用内,先注册的接收器先收到广播。



 2.从广播的发送方式来分,分为以下3种:

普通广播:通过context. sendBroadcast或者context. sendBroadcastAsUser发送给当前系统中所有注册的接受者,也就是只要注册了就会接收到;

有序广播:接收者按照优先级处理广播,并且前面处理广播的接受者可以中止广播的传递,一般通过context. sendOrderedBroadcast或者context. sendOrderedBroadcastAsUser;

不过目前为止,程序发出的都还是标准广播,如果需要发送有序广播,只需要修改一行代码,即将 sendBroadcast()方法改成 sendOrderedBroadcast()方法

sendOrderedBroadcast()方法接收两个参数,第一个参数仍然是 Intent,第二个参数是一个与权限相关的字符串。


粘性广播:可以发送给以后注册的接受者,意思是系统会将前面的粘性广播保存在AMS中,一旦注册了与以保存的性广播符合的广播,在注册结束后会立即收到广播,一般通过context. sendStickyBroadcast或context.sendStickyOrderedBroadcast来发送,从字面上看,可以看出来粘性广播也分为普通粘性广播和有序粘性广播。

      根据广播的类型,一般常用的就是普通广播和粘性广播,网络切换的广播就是一种粘性广播。

Sticky Broadcast:粘性广播(在 android 5.0/api 21中deprecated,不再推荐使用,相应的还有粘性有序广播,同样已经deprecated)。

既然已经deprecated,此处不再多


为了能够简单地解决广播安全性问题,Android 引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。

本地广播的用法并不复杂,主要就是使用了一个LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法。


1.Widget的原理就是一个特殊的广播

2.多媒体中用到的一种特殊的广播
sendStickyBroadcast广播


注册,发送,接受都相同的Action

在Oncreart放方法中注册
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("cn.abel.action.broadcast");
this.registerReceiver(new MyBroadcastReciver(), intentFilter);


有些广播中还需要加入一些特殊的元素(用来过滤的) IntentFilter


这种广播只能动态注册(内部类
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){ 
        @Override 
        public void onReceive(Context context, Intent intent) { 
            String action = intent.getAction(); 
            if(action.equals(ACTION_NAME)){ 
                Toast.makeText(Test.this, "处理action名字相对应的广播", 200); 
            } 
        } 
         
    }; 

  Intent intent = new Intent();
   intent.setAction("cn.abel.action.broadcast");   
   //要发送的内容
   intent.putExtra("author", "Abel");   
   //发送 一个无序广播
   MainActivity.this.sendBroadcast(intent);

或者:构造方法

  Intent intent = new Intent("cn.abel.action.broadcast");    
   //要发送的内容
   intent.putExtra("author", "Abel");   
   //发送 一个无序广播
   MainActivity.this.sendBroadcast(intent);



 // Intent intentAlarm = new Intent(this,
 // WeatherWidgetUpdateService.class);
 // intentAlarm.setAction("android.intent.action.UPDATE_WEATHER_BY_ALERM");//
 // 这个PendingIntent可以说是
Intent intentAlarm = new Intent("android.intent.action.UPDATE_WEATHER_BY_ALERM");
用Intent跳转和用Intent发送广播
取消注册BroadcastReceiver:


广播的生命周期
1.动态(自己定义的)
2.静态=======系统广播注册(开机,桌面启动,或者时间和日期的变化)


跳程序启动,setclass的方式
Intent intent = new Intent();
intent.setClassName("android.car.app.radio", "android.car.app.radio.RadioMain");
startActivity(intent);


广播:
注册广播和接受广播,没有发送广播

有的是没有接受广播,有的是没有注册(静态注册的)
静态注册的广播接受器是写一个还是?



注册和广播接收弄在一个类中,这样才好操作
如果不在一个类,就最好用静态注册------


问题:
注册不是同一个实例,但是接受是同一个实例?可以吗?

===================================================
BroadcastReceiver mSDCardReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub

String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
// 把界面清空
mProgressView.setVisibility(View.GONE);
mApkInfoList.clear();
mInstallApkAdapter.changeData(mApkInfoList);
mNoSdcardView.setVisibility(View.VISIBLE);
} else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
// showProgressDialog();
mProgressView.setVisibility(View.VISIBLE);
mNoSdcardView.setVisibility(View.GONE);
initData();
}
}
};

class SDcardBroadCast extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
// 把界面清空
mProgressView.setVisibility(View.GONE);
mApkInfoList.clear();
mInstallApkAdapter.changeData(mApkInfoList);
mNoSdcardView.setVisibility(View.VISIBLE);
} else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
// showProgressDialog();
mProgressView.setVisibility(View.VISIBLE);
mNoSdcardView.setVisibility(View.GONE);
initData();
}else if(action.equals(BROADCAST_INSTALLAPK_UPDATE)){
initData();
}

}

}

注册的时候产生多个new IntentFilter();
IntentFilter intentSdcard = new IntentFilter();


收不到广播的原因=====广播的过滤机制
有些附加的东西要分开注册====车机小帮手


1.静态类有什么……………………
不太好和外界交换的
只能调用外界的静态方法

QQ截图20140519112457.png


QQ截图20140519112441.png


QQ截图20140519112511.png




1.为什么需要广播机制呢?
在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,
那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它们之间可以用来通信的方式就更多了,这样看来,广播机制似乎是多余的。
然而,广播机制却是不可替代的,它和Binder机制不一样的地方在于,
广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是,系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。

2.是否使用过本地广播,和全局广播有什么差别?


因广播数据在本应用范围内传播,不用担心隐私数据泄露的问题。 不用担心别的应用伪造广播,造成安全隐患。 相比在系统内发送全局广播,它更高效。


 LocalBroadcastManager


3.广播的接收过程

ContextImpl--------AMS----broadcastQueue------------最终到了ActivityThread启动



和Activity的启动过程一样,通过一些了的binder机制,最后ActivityThread启动广播,AMS是其中的一个部分


广播的发送:用的也是AMS里面的sendBroadCast();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值