广播Intent的三种方式总结
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则会抛出异常。
这个解释看了后似懂非懂的,于是就写了个例子试了下,下面把代码贴出了,希望能还大家一起讨论
- package com.android.test;
- import android.app.Activity;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class StickyBroadcastTest extends Activity {
- private Button mSendBroadcast;
- private Button mSendStickyBroadcast;
- private Button mNextActivity;
- private Context mContext;
- private int mStickyBrcCount;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mContext = getApplicationContext();
- mSendBroadcast = (Button)findViewById(R.id.broadcast);
- mSendStickyBroadcast = (Button)findViewById(R.id.stickybroadcast);
- mNextActivity = (Button)findViewById(R.id.next_activity);
- mSendBroadcast.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent("com.android.action.broadcast");
- mContext.sendBroadcast(intent);
- }
- });
- mSendStickyBroadcast.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mStickyBrcCount++;
- Intent intent = new Intent("com.android.action.sticky.broadcast");
- intent.putExtra("sent_count", mStickyBrcCount);
- mContext.sendStickyBroadcast(intent);
- }
- });
- mNextActivity.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(StickyBroadcastTest.this, MyReceiverActivity.class);
- startActivity(intent);
- }
- });
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- mStickyBrcCount = 0;
- }
- }
- //MyReceiverActivity
- package com.android.test;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.util.Log;
- public class MyReceiverActivity extends Activity {
- private IntentFilter mIntentFilter;
- private final static String TAG = "MyReceiverActivity";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.broadcast_receiver);
- mIntentFilter = new IntentFilter();
- mIntentFilter.addAction("com.android.action.broadcast");
- mIntentFilter.addAction("com.android.action.sticky.broadcast");
- }
- private BroadcastReceiver mReceiver = new BroadcastReceiver () {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- int count = intent.getIntExtra("sent_count", -1);
- Log.d(TAG, "action = " + action + "and count = " + count);
- //context.removeStickyBroadcast(intent);
- }
- };
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- super.onPause();
- unregisterReceiver(mReceiver);
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- registerReceiver(mReceiver, mIntentFilter);
- }
- }
运行结果如图:
首先点击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方法可以帮你,处理完了后就将它删除吧。
相似的例子:
- package com.android.testbroadcast;
- import android.app.Activity;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity {
- Button btnSendi;
- Button btnSends;
- Button btnStart;
- Context mContext;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btnSendi=(Button) findViewById(R.id.sendi);
- btnSends=(Button) findViewById(R.id.sends);
- btnStart=(Button) findViewById(R.id.start);
- mContext=getApplicationContext();
- btnSendi.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Intent intent = new Intent();
- intent.setAction("com.android.my.action");
- intent.setFlags(1);
- mContext.sendBroadcast(intent);
- }
- });
- btnStart.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Intent intent = new Intent(MainActivity.this,ReceiverActivity.class);
- startActivity(intent);
- }
- });
- btnSends.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Intent intent = new Intent();
- intent.setAction("com.android.my.action.sticky");
- intent.setFlags(2);
- mContext.sendStickyBroadcast(intent);
- }
- });
- }
- }
- package com.android.testbroadcast;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.wifi.WifiManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class ReceiverActivity extends Activity {
- private IntentFilter mIntentFilter;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mIntentFilter = new IntentFilter();
- mIntentFilter.addAction("com.android.my.action");
- mIntentFilter.addAction("com.android.my.action.sticky");
- }
- private BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- System.out.println("action"+action);
- }
- };
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- registerReceiver(mReceiver, mIntentFilter);
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- super.onPause();
- unregisterReceiver(mReceiver);
- }
- }
在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的三种方式总结的更多相关文章
- dubbo服务运行的三种方式
dubbo服务运行,也就是让生产服务的进程一直启动.如果生产者进程挂掉,也就不存在生产者,消费者不能进行消费. Dubbo服务运行的三种方式如下:1.使用Servlet容器运行(Tomcat.Jett ...
- Android录制音频的三种方式
对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活.所以有提供了另外的俩种. 下边来介绍下这三种录制的方式; 1.通过Intent调用系统的录音器功能,然后在录制 ...
- uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式
前言: 关于H5的调用Android原生方法的方式有很多,在该片文章中我主要简单介绍三种与Android原生方法交互的方式. 一.H5+方法调用android原生方法 H5+ Android开发规范官 ...
- 监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile
大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...
- iOS字体加载三种方式
静态加载 动态加载 动态下载苹果提供的多种字体 其他 打印出当前所有可用的字体 检查某字体是否已经下载 这是一篇很简短的文章,介绍了 iOS 自定义字体加载的三种方式. 静态加载 这个可以说是最简单最 ...
- 0036 Java学习笔记-多线程-创建线程的三种方式
创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...
- 【整理】Linux下中文检索引擎coreseek4安装,以及PHP使用sphinx的三种方式(sphinxapi,sphinx的php扩展,SphinxSe作为mysql存储引擎)
一,软件准备 coreseek4.1 (包含coreseek测试版和mmseg最新版本,以及测试数据包[内置中文分词与搜索.单字切分.mysql数据源.python数据源.RT实时索引等测 ...
- JDBC的批处理操作三种方式 pstmt.addBatch()
package lavasoft.jdbctest; import lavasoft.common.DBToolkit; import java.sql.Connection; import java ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
随机推荐
- php常用方法一
1.用户名用***替换 /** * 用户名中间用***替换 * @param string $str 需要替换的字符串 * @param int $len 需要替换的位数 * @param strin ...
- Nginx的安装与升级
1,构建Nginx服务器; 2.升级版本; 一, 构建Nginx服务器 1.使用源码包安装nginx软件包 # yum -y install gcc pcre-devel openssl-devel ...
- windows 命令行 for 用法
for /r 目录名 %i in (匹配模式1,匹配模式2) do @echo %i for /r SATA %i in (*.txt) do @echo %i D:\REY\test>for ...
- ES2015 模板字符串 ``
js中类似`${xx,yy}`的语句是什么意思? `string` 是模板字符串,ES2015新增的符号. var x = 'a', y = 'b'; var z = `${x,y}`; //'b' ...
- jmeter搭建
jdk 1.8的地址 链接:https://pan.baidu.com/s/1eEyYbzo1Tfbvbmf_vN2yUA 密码:6dxi 1.安装JDK 选择安装目录 安装过程中会出现两次 安装提 ...
- Mysql笔记2-----重要小点
1.逻辑删除:
- C语言提高 (3) 第三天 二级指针的三种模型 栈上指针数组、栈上二维数组、堆上开辟空间
1 作业讲解 指针间接操作的三个必要条件 两个变量 其中一个是指针 建立关联:用一个指针指向另一个地址 * 简述sizeof和strlen的区别 strlen求字符串长度,字符数组到’\0’就结束 s ...
- Iterator和for...of
Iterator和for...of 什么是Iterator ES6中的Map 和 Set ,再加上之前的数组和对象,这样就有了四种数据集合,用户可以组合使用它们,定义自己的数据结构.这时,我们就需要一 ...
- Project Euler 41 Pandigital prime( 米勒测试 + 生成全排列 )
题意:如果一个n位数恰好使用了1至n每个数字各一次,我们就称其为全数字的.例如,2143就是一个4位全数字数,同时它恰好也是一个素数. 最大的全数字的素数是多少? 思路: 最大全排列素数可以从 n = ...
- 训练1-H
小明今年3岁了, 现在他已经能够认识100以内的非负整数, 并且能够进行100以内的非负整数的加法计算. 对于大于等于100的整数, 小明仅保留该数的最后两位进行计算, 如果计算结果大于等于100, ...