说一说Android中的广播那回事
2016-07-04 11:46
561 查看
好久没有写过广播了 今天写了一个极光推送,,要用到广播才发现是这么的陌生,哎 搞了一个垃圾项目 啥都没有,,都快堕落成一个菜逼了,,写个博客做个回忆。
/**
* 广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。
* 普通广播是完全异步的,可以在同一时刻(逻辑上)被所有广播接收者接收到,消息传递的效率比较高,
*但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;
* 然而有序广播是按照接收者声明的优先级别
*(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。
*也可以调用IntentFilter对象的setPriority()进行设置),
*被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。
* A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
* Context.sendBroadcast()
* 发送的是普通广播,所有订阅者都有机会获得并进行处理。
* Context.sendOrderedBroadcast()
*发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,
* 前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),
* 如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。
* 对于有序广播,前面的接收者可以将处理结果存放进广播Intent,
* 然后传给下一个接收者。
*
* 静态订阅广播又叫:常驻型广播,当你的应用程序关闭了,如果有广播信息来,
* 你写的广播接收器同样的能接受到,他的注册方式就是在你的应用程序中的AndroidManifast.xml进行订阅的。
*动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,
* 比如你在activity中的onCreate或者onResume中订阅广播,同时你必须在onDestory或者onPause中取消广播订阅。
* 不然会报异常,这样你的广播接收器就一个非常驻型的了。
*这里面还有一个细节那就是这两种订阅方式,在发送广播的时候需要注意的是:
* 动态注册的时候使用的是隐式intent方式的,所以在发送广播的时候需要使用隐式Intent去发送,
* 不然是广播接收者是接收不到广播的,这一点要注意。但是静态订阅的时候,
* 因为在AndroidMainfest.xml中订阅的,
* 所以在发送广播的时候使用显示Intent和隐式Intent都可以(当然这个只针对于我们自己定义的广播接收者),
* 所以以防万一,我们一般都采用隐式Intent去发送广播。
* */
先看一下清单文件,Activity,BroadcastReceiver,Service,ContentproVider这四大组件只要使用则必须在清单文件中去注册
(1.)先来看一下静态注册广播的使用方法
在清单文件中注册 并注明action
说到了这个Dialog就要说一下这个上下文的问题就有context和getApplicationContext()
// Context:什么是上下文?—->运行环境.
// 整个程序的运行环境:
// Context applicationContext = getApplicationContext();
// Activity:只是当前这个Activity的环境.
// 通常情况下,能够使用Activity的地方,都可以使用getApplicationContext()方法.
// 但是在创建Dialog的时候,除外:
// 会产生一个坏的令牌异常.
// Caused by: android.view.WindowManager$BadTokenException:
// Unable to add window – token null is not for an application
所以在弹出上下文的时候,只能使用当前Activity的上下文
(2)动态注册广播接收器
动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,
相应的广播接收器
(3.)有序广播的发送
有序广播是按照接收者声明的优先级别
*(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。
*也可以调用IntentFilter对象的setPriority()进行设置),
*被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。
* A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
* Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,
* 前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),
* 如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。
* 对于有序广播,前面的接收者可以将处理结果存放进广播Intent,
* 然后传给下一个接收者。
对应两个优先级不同的广播接收器
/**
* 广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。
* 普通广播是完全异步的,可以在同一时刻(逻辑上)被所有广播接收者接收到,消息传递的效率比较高,
*但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;
* 然而有序广播是按照接收者声明的优先级别
*(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。
*也可以调用IntentFilter对象的setPriority()进行设置),
*被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。
* A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
* Context.sendBroadcast()
* 发送的是普通广播,所有订阅者都有机会获得并进行处理。
* Context.sendOrderedBroadcast()
*发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,
* 前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),
* 如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。
* 对于有序广播,前面的接收者可以将处理结果存放进广播Intent,
* 然后传给下一个接收者。
*
* 静态订阅广播又叫:常驻型广播,当你的应用程序关闭了,如果有广播信息来,
* 你写的广播接收器同样的能接受到,他的注册方式就是在你的应用程序中的AndroidManifast.xml进行订阅的。
*动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,
* 比如你在activity中的onCreate或者onResume中订阅广播,同时你必须在onDestory或者onPause中取消广播订阅。
* 不然会报异常,这样你的广播接收器就一个非常驻型的了。
*这里面还有一个细节那就是这两种订阅方式,在发送广播的时候需要注意的是:
* 动态注册的时候使用的是隐式intent方式的,所以在发送广播的时候需要使用隐式Intent去发送,
* 不然是广播接收者是接收不到广播的,这一点要注意。但是静态订阅的时候,
* 因为在AndroidMainfest.xml中订阅的,
* 所以在发送广播的时候使用显示Intent和隐式Intent都可以(当然这个只针对于我们自己定义的广播接收者),
* 所以以防万一,我们一般都采用隐式Intent去发送广播。
* */
先看一下清单文件,Activity,BroadcastReceiver,Service,ContentproVider这四大组件只要使用则必须在清单文件中去注册
<!-- 无序广播注册START --> <receiver android:name=".receiver.UnSortBroadcastReceiver"> <intent-filter > <action android:name="static"/> </intent-filter> </receiver> <!-- 无序广播注册END --> <receiver android:name=".receiver.SortBroadcastReceiverA"> <intent-filter android:priority="999"> <action android:name="order"/> </intent-filter> </receiver> <receiver android:name=".receiver.SortBroadcastReceiverB"> <intent-filter android:priority="1000"> <action android:name="order"/> </intent-filter> </receiver>
(1.)先来看一下静态注册广播的使用方法
在清单文件中注册 并注明action
public class StaticRegisterBroadcastActivity extends AppCompatActivity { //静态订阅广播 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //使用静态的方式注册广播,可以使用显示意图进行发送广播 Intent intent = new Intent(); // 接受条件 intent.setAction("static"); //发送内容 intent.putExtra("key","小葵花妈妈开课了,啦啦啦!大喇叭..."); // 发无序广播: sendBroadcast(intent); } }); }
对应的广播接收器
/** * Created by xuenan on 2016/7/1. */ // 接受并处理广播的方法.这个方法是在主线程中运行的,所以不要做耗时的操作. // 如果主线程被阻塞大约10秒钟,会产生ANR异常.不要在这个方法中弹Dialog. public class UnSortBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if ("static".equals(intent.getAction())) { String value = intent.getStringExtra("key"); Log.e("UnSortBroadcastReceiver",value); } } }
说到了这个Dialog就要说一下这个上下文的问题就有context和getApplicationContext()
// Context:什么是上下文?—->运行环境.
// 整个程序的运行环境:
// Context applicationContext = getApplicationContext();
// Activity:只是当前这个Activity的环境.
// 通常情况下,能够使用Activity的地方,都可以使用getApplicationContext()方法.
// 但是在创建Dialog的时候,除外:
// 会产生一个坏的令牌异常.
// Caused by: android.view.WindowManager$BadTokenException:
// Unable to add window – token null is not for an application
所以在弹出上下文的时候,只能使用当前Activity的上下文
(2)动态注册广播接收器
动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,
public class DynamicRegisterBroadcastActivity extends AppCompatActivity { //使用动态的方式注册广播 private DynamicReceiver receiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction("dynamic"); intent.putExtra("dynamic", "动态注册的广播接收器..."); //发送无序广播 sendBroadcast(intent); } }); } @Override protected void onResume() { super.onResume(); receiver = new DynamicReceiver(); IntentFilter filter = new IntentFilter(); //filter.setPriority(1000);//代码设置广播的优先级,如果是发送无序广播,这行代码没有用 filter.addAction("dynamic"); // 动态注册广播接收器 registerReceiver(receiver, filter); } @Override protected void onPause() { super.onPause(); // 取消注册广播接收器 if (receiver != null) { unregisterReceiver(receiver); } } }
相应的广播接收器
public class DynamicReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if ("dynamic".equals(intent.getAction())) { String value = intent.getStringExtra("dynamic"); Log.e("DynamicReceiver",value); } } }
(3.)有序广播的发送
有序广播是按照接收者声明的优先级别
*(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。
*也可以调用IntentFilter对象的setPriority()进行设置),
*被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。
* A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
* Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,
* 前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),
* 如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。
* 对于有序广播,前面的接收者可以将处理结果存放进广播Intent,
* 然后传给下一个接收者。
public class OrderedBroadcastActivity extends AppCompatActivity { //有序广播 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //使用静态的方式注册广播,可以使用显示意图进行发送广播 Intent intent = new Intent(); // 接受条件 intent.setAction("order"); //发送内容 intent.putExtra("key","这是发送的有序广播"); // 发无序广播: //sendBroadcast(intent); //发送有序广播 sendOrderedBroadcast(intent,null); } }); } }
对应两个优先级不同的广播接收器
//有序广播A public class SortBroadcastReceiverA extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = getResultExtras(true); String content = bundle.getString("next_receiver"); Log.e("Demo:",content+""); } }
//有序广播A //有序广播的特点,可以看出是一个同步的动作, //接收者之间可以进行数据的交互(上一个传递数据给下一个),也可以控制广播的终止。 public class SortBroadcastReceiverB extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if ("order".equals(intent.getAction())) { String value = intent.getStringExtra("key"); Log.e("DynamicReceiver",value); } //abortBroadcast();//终止此次广播的传输,,不再传递给SortBroadcastReceiverA //也可以再传递给SortBroadcastReceiverA Bundle bundle = new Bundle(); bundle.putString("next_receiver", "下一个广播接收者"); setResultExtras(bundle); } }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories