1.android有序广播和无序广播的区别

BroadcastReceiver所对应的广播分两类:普通广播和有序广播。

普通广播通过Context.sendBroadcast()方法来发送。它是完全异步的。

所有的receivers接收器的执行顺序不确定。    因此,所有的receivers接收器接收broadcast的顺序不确定。

这种方式效率更高。但是BroadcastReceiver无法使用setResult系列,getResult系列及abort系列API

有序广播是通过Context.sendOrderedBroadcast来发送。所有的receiver依次执行。

BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播让,使用该广播不再传送到别的BroadcastReceiver。

可以通过在intent-filter中设置android:priority属性来设置receiver的优先级。优先级相同的receiver其执行顺序不确定。

如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。

有序广播,即从优先级别最高的广播接收器开始接收,接收完了如果没有丢弃,就下传给下一个次高优先级别的广播接收器进行处理,依次类推,直到最后。

2.sendBroadcast和sendStickyBroadcast的区别

sendBroadcast中发出的intent在ReceverActivity不处于onResume状态是无法接受到的,即使后面再次使其处于该状态也无法接受到。

而sendStickyBroadcast发出的Intent当ReceverActivity重新处于onResume状态之后就能重新接受到其Intent.这就是the Intent will be held to be re-broadcast to future receivers这句话的表现。就是说sendStickyBroadcast发出的最后一个Intent会被保留,下次当Recevier处于活跃的时候,又会接受到它。

3. FLAG的影响 
1)FLAG_RECEIVER_REPLACE_PENDING 
这个flag 将会将之前的Intent 替代掉。加了这个flag,在发送一系列的这样的Intent 之后, 中间有些Intent 有可能在你还没有来得及处理的时候,就被替代掉了。 
2)FLAG_RECEIVER_REGISTERED_ONLY: 
如果Intent 加了这个Flag, 那么在Androidmanifest.xml 里定义的Receiver 是接收不到这样的Intent 的。 
3)FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT: 
如果Intent加了这个Flag,那么在启动检查时只能接受在代码中注册的Receiver。这个标志是唯一使用的系统服务作为一种方便避免实施更复杂的机制在启动完成检测。

sendStickyBroadcast 的理解和使用

要知道区别首先需要看一下Android Developers Reference, 它可是我们最好的老师了,sendBroadcast 大家应该都会用了我就不赘述了,下面来看看sendStickyBroadcast

google官方的解释是:

Perform a sendBroadcast(Intent) that is "sticky," meaning the Intent you are sending stays around after the broadcast is complete, so that others can quickly retrieve that data through the return value ofregisterReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same as sendBroadcast(Intent).

You must hold the BROADCAST_STICKY permission in order to use this API. If you do not hold that permission,SecurityException will be thrown.

大概的意思是说: 发出的广播会一直滞留(等待),以便有人注册这则广播消息后能尽快的收到这条广播。其他功能与sendBroadcast相同。但是使用sendStickyBroadcast 发送广播需要获得BROADCAST_STICKY permission,如果没有这个permission则会抛出异常。

这个解释看了后似懂非懂的,于是就写了个例子试了下,下面把代码贴出了,希望能还大家一起讨论

  1. package com.android.test;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.widget.Button;
  9. public class StickyBroadcastTest extends Activity {
  10. private Button mSendBroadcast;
  11. private Button mSendStickyBroadcast;
  12. private Button mNextActivity;
  13. private Context mContext;
  14. private int mStickyBrcCount;
  15. /** Called when the activity is first created. */
  16. @Override
  17. public void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.main);
  20. mContext = getApplicationContext();
  21. mSendBroadcast = (Button)findViewById(R.id.broadcast);
  22. mSendStickyBroadcast = (Button)findViewById(R.id.stickybroadcast);
  23. mNextActivity = (Button)findViewById(R.id.next_activity);
  24. mSendBroadcast.setOnClickListener(new OnClickListener() {
  25. @Override
  26. public void onClick(View v) {
  27. Intent intent = new Intent("com.android.action.broadcast");
  28. mContext.sendBroadcast(intent);
  29. }
  30. });
  31. mSendStickyBroadcast.setOnClickListener(new OnClickListener() {
  32. @Override
  33. public void onClick(View v) {
  34. mStickyBrcCount++;
  35. Intent intent = new Intent("com.android.action.sticky.broadcast");
  36. intent.putExtra("sent_count", mStickyBrcCount);
  37. mContext.sendStickyBroadcast(intent);
  38. }
  39. });
  40. mNextActivity.setOnClickListener(new OnClickListener() {
  41. @Override
  42. public void onClick(View v) {
  43. Intent intent = new Intent(StickyBroadcastTest.this, MyReceiverActivity.class);
  44. startActivity(intent);
  45. }
  46. });
  47. }
  48. @Override
  49. protected void onResume() {
  50. // TODO Auto-generated method stub
  51. super.onResume();
  52. mStickyBrcCount = 0;
  53. }
  54. }
  55. //MyReceiverActivity
  56. package com.android.test;
  57. import android.app.Activity;
  58. import android.content.BroadcastReceiver;
  59. import android.content.Context;
  60. import android.content.Intent;
  61. import android.content.IntentFilter;
  62. import android.os.Bundle;
  63. import android.util.Log;
  64. public class MyReceiverActivity extends Activity {
  65. private IntentFilter mIntentFilter;
  66. private final static String TAG = "MyReceiverActivity";
  67. /** Called when the activity is first created. */
  68. @Override
  69. public void onCreate(Bundle savedInstanceState) {
  70. super.onCreate(savedInstanceState);
  71. setContentView(R.layout.broadcast_receiver);
  72. mIntentFilter = new IntentFilter();
  73. mIntentFilter.addAction("com.android.action.broadcast");
  74. mIntentFilter.addAction("com.android.action.sticky.broadcast");
  75. }
  76. private BroadcastReceiver  mReceiver = new BroadcastReceiver () {
  77. @Override
  78. public void onReceive(Context context, Intent intent) {
  79. final String action = intent.getAction();
  80. int count = intent.getIntExtra("sent_count", -1);
  81. Log.d(TAG, "action = " + action + "and count = " + count);
  82. //context.removeStickyBroadcast(intent);
  83. }
  84. };
  85. @Override
  86. protected void onPause() {
  87. // TODO Auto-generated method stub
  88. super.onPause();
  89. unregisterReceiver(mReceiver);
  90. }
  91. @Override
  92. protected void onResume() {
  93. // TODO Auto-generated method stub
  94. super.onResume();
  95. registerReceiver(mReceiver, mIntentFilter);
  96. }
  97. }

运行结果如图:

首先点击next Activity从代码中可以看到receiver已经注册,但Log无输出,这是当然的了~~~因为没有广播发出自然就不会有人响应了。

按back后退到上图

下面分别点击send broadcast 和 send stickybroadcast按钮,随便点击几次,此时对应的receiver并没有注册,所以是不会有人响应这两条广播的。然后点击next activity,当打开新的activity后对应的receiver被注册,此时从日志中就能看出已经收到了send stickybroadcast发出的广播,但没有send broadcast发出的广播。这就是sendStickyBroadcast的特别之处,它将发出的广播保存起来,一旦发现有人注册这条广播,则立即能接收到。

日志打印为: action = com.android.action.sticky.broadcastand count = 4

从上面的日志信息可以看出sendStickyBroadcast只保留最后一条广播,并且一直保留下去,这样即使已经处理了这条广播但当再一次注册这条广播后依然可以收到它。

如果你只想处理一遍,removeStickyBroadcast方法可以帮你,处理完了后就将它删除吧。

相似的例子:

  1. package com.android.testbroadcast;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.widget.Button;
  9. public class MainActivity extends Activity {
  10. Button btnSendi;
  11. Button btnSends;
  12. Button btnStart;
  13. Context mContext;
  14. /** Called when the activity is first created. */
  15. @Override
  16. public void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.main);
  19. btnSendi=(Button) findViewById(R.id.sendi);
  20. btnSends=(Button) findViewById(R.id.sends);
  21. btnStart=(Button) findViewById(R.id.start);
  22. mContext=getApplicationContext();
  23. btnSendi.setOnClickListener(new OnClickListener(){
  24. @Override
  25. public void onClick(View v) {
  26. // TODO Auto-generated method stub
  27. Intent intent = new Intent();
  28. intent.setAction("com.android.my.action");
  29. intent.setFlags(1);
  30. mContext.sendBroadcast(intent);
  31. }
  32. });
  33. btnStart.setOnClickListener(new OnClickListener(){
  34. @Override
  35. public void onClick(View v) {
  36. // TODO Auto-generated method stub
  37. Intent intent = new Intent(MainActivity.this,ReceiverActivity.class);
  38. startActivity(intent);
  39. }
  40. });
  41. btnSends.setOnClickListener(new OnClickListener(){
  42. @Override
  43. public void onClick(View v) {
  44. // TODO Auto-generated method stub
  45. Intent intent = new Intent();
  46. intent.setAction("com.android.my.action.sticky");
  47. intent.setFlags(2);
  48. mContext.sendStickyBroadcast(intent);
  49. }
  50. });
  51. }
  52. }
  1. package com.android.testbroadcast;
  2. import android.app.Activity;
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.content.IntentFilter;
  7. import android.net.wifi.WifiManager;
  8. import android.os.Bundle;
  9. import android.view.View;
  10. import android.view.View.OnClickListener;
  11. import android.widget.Button;
  12. public class ReceiverActivity extends Activity {
  13. private IntentFilter mIntentFilter;
  14. /** Called when the activity is first created. */
  15. @Override
  16. public void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.main);
  19. mIntentFilter = new IntentFilter();
  20. mIntentFilter.addAction("com.android.my.action");
  21. mIntentFilter.addAction("com.android.my.action.sticky");
  22. }
  23. private BroadcastReceiver mReceiver = new BroadcastReceiver() {
  24. @Override
  25. public void onReceive(Context context, Intent intent) {
  26. final String action = intent.getAction();
  27. System.out.println("action"+action);
  28. }
  29. };
  30. @Override
  31. protected void onResume() {
  32. // TODO Auto-generated method stub
  33. super.onResume();
  34. registerReceiver(mReceiver, mIntentFilter);
  35. }
  36. @Override
  37. protected void onPause() {
  38. // TODO Auto-generated method stub
  39. super.onPause();
  40. unregisterReceiver(mReceiver);
  41. }
  42. }

在MainActivity里面会有sendBroadcast和sendStickyBroacat.在ReceverActivity里面通 过BroadcastReceiver来接收这两个消息,在ReceiverActivity里是通过代码来注册Recevier而不是在 Manifest里面注册的。所以通过sendBroadcast中发出的intent在ReceverActivity不处于onResume状态是无 法接受到的,即使后面再次使其处于该状态也无法接受到。而sendStickyBroadcast发出的Intent当ReceverActivity重 新处于onResume状态之后就能重新接受到其Intent.这就是the Intent will be held to be re-broadcast to future receivers这句话的表现。就是说sendStickyBroadcast发出的最后一个Intent会被保留,下次当Recevier处于活跃的 时候,又会接受到它。

广播Intent的三种方式总结的更多相关文章

  1. dubbo服务运行的三种方式

    dubbo服务运行,也就是让生产服务的进程一直启动.如果生产者进程挂掉,也就不存在生产者,消费者不能进行消费. Dubbo服务运行的三种方式如下:1.使用Servlet容器运行(Tomcat.Jett ...

  2. Android录制音频的三种方式

    对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活.所以有提供了另外的俩种. 下边来介绍下这三种录制的方式; 1.通过Intent调用系统的录音器功能,然后在录制 ...

  3. uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式

    前言: 关于H5的调用Android原生方法的方式有很多,在该片文章中我主要简单介绍三种与Android原生方法交互的方式. 一.H5+方法调用android原生方法 H5+ Android开发规范官 ...

  4. 监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile

    大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...

  5. iOS字体加载三种方式

    静态加载 动态加载 动态下载苹果提供的多种字体 其他 打印出当前所有可用的字体 检查某字体是否已经下载 这是一篇很简短的文章,介绍了 iOS 自定义字体加载的三种方式. 静态加载 这个可以说是最简单最 ...

  6. 0036 Java学习笔记-多线程-创建线程的三种方式

    创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...

  7. 【整理】Linux下中文检索引擎coreseek4安装,以及PHP使用sphinx的三种方式(sphinxapi,sphinx的php扩展,SphinxSe作为mysql存储引擎)

          一,软件准备 coreseek4.1 (包含coreseek测试版和mmseg最新版本,以及测试数据包[内置中文分词与搜索.单字切分.mysql数据源.python数据源.RT实时索引等测 ...

  8. JDBC的批处理操作三种方式 pstmt.addBatch()

    package lavasoft.jdbctest; import lavasoft.common.DBToolkit; import java.sql.Connection; import java ...

  9. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

随机推荐

  1. javascript中in用法介绍

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 【技术累积】【点】【java】【3】编译和反编译

    闲聊 擦,打脸了,但打完了还是得继续写呗,水着水着看呗. 概述 理解的不深入,但是实用. 总而言之:编译,是将书写的代码翻译为机器能够理解的代码:反编译,则是相反的过程. 来源在于语言的等级,一般认为 ...

  3. IE兼容opacity

    filter:alpha(opacity=80); opacity: 0.57; /* Firefox, Safari(WebKit), Opera) filter: "alpha(opac ...

  4. (转)基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面

    http://www.cnblogs.com/wuhuacong/p/3669575.html 最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开 ...

  5. CorelDRAW快速制作绚丽的彩色透明心形

    今天小编分享给小伙伴们用CorelDRAW打造绚丽的彩色透明心形.主要使用完美形状组中的心形造型制作出心形图案,经过对图形的模糊操作,再经过图框精确剪裁,最后添加一个彩虹渐变色实现绚丽的彩色透明效果. ...

  6. 企业级任务调度框架Quartz(6) 任务调度器(Scheduler)

    前序:      我们已经在前面的内容能里看到了,我们用 Scheduler 来管理我们的 Job:创建并关联触发器以使 Job 能被触发执行:以及如可选择 calendar 为给定的时程安排提供更多 ...

  7. day02_20190106 基础数据类型 编码 运算符

    一.格式化输出 name = input('请输入姓名') age = input('请输入年龄') hobby = input('请输入爱好') job = input('请输入你的工作') # m ...

  8. Arguments Optional FreeCodeCamp

    function add() { if(typeof arguments[0] !== "number" || (arguments.length > 1 && ...

  9. 路飞学城Python-Day78

    17-静态文件配置1 静态的文件的配置不能直接将CSS.JS文件直接放在templates的文件夹中 要将所有的静态文件放在static的文件夹中,然后配置上静态文件static的路径 要想访问Dja ...

  10. Python面向对象之静态方法、静态方法与类方法

    静态属性: 类调用函数属性时,需要先将类实例化,再将实例作为函数属性传入:类的实例调用函数属性时需要在后面加括号. class Building: def __init__(self, name, o ...