今天闲来无事,研究了下Android的Broadcast,发现Broadcast在Android系统中担任着很艰巨的角色。

Broadcast是Android的四大组件之一;Broadcast分为普通广播和无序广播。

有序广播可以设置优先级,优先级高的接收者可以终止广播的传播。但是在普通广播中,优先级高的就不能终止广播的传播。

     /**
* 发送一个普通广播
*/
private void sendBroadcasts() {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("com.zhj.test");
intent.putExtra("msg", "hello world!");//参数
sendBroadcast(intent);
} /**
* 发送一个有序广播
*/
private void sendSortBroadcasts() {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("com.zhj.test");
intent.putExtra("msg", "hello world!");//参数
sendOrderedBroadcast(intent, null);
}

广播按注册方式分为动态注册和静态注册;

(1)静态注册:

静态注册是直接在AndroidManifest.xml中配置,规则如下:

<receiver android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
. . .
</receiver>

其中,需要注意的属性
android:exported  ——此broadcastReceiver能否接收其他App的发出的广播,这个属性默认值有点意思,其默认值是由receiver中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。(同样的,activity/service中的此属性默认值一样遵循此规则)同时,需要注意的是,这个值的设定是以application或者application user id为界的,而非进程为界(一个应用中可能含有多个进程);
android:name  —— 此broadcastReceiver类名;
android:permission  ——如果设置,具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收;
android:process  ——broadcastReceiver运行所处的进程。默认为app的进程。可以指定独立的进程(Android四大基本组件都可以通过此属性指定自己的独立进程)

常见的注册方式为:

<receiver android:name=".MyBroadcastReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

(2)动态注册:

动态注册时,无须在AndroidManifest中注册<receiver/>组件。直接在代码中通过调用Context的registerReceiver函数,可以在程序中动态注册BroadcastReceiver。registerReceiver的定义形式如下:

registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)

下面是一个动态注册广播的例子:

     private static SortedBroadcast mSortedBroadcast = null;
//注册广播
private void registerHomeKeyReceiver(Context context) {
mSortedBroadcast = new SortedBroadcast();
final IntentFilter homeFilter = new IntentFilter(
Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
homeFilter.setPriority(1000);
context.registerReceiver(mSortedBroadcast, homeFilter);
}
//销毁广播
private void unregisterHomeKeyReceiver(Context context) {
if (null != mSortedBroadcast) {
context.unregisterReceiver(mSortedBroadcast);
}
} @Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
registerHomeKeyReceiver(this);//可以不再此处注册
} @Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterHomeKeyReceiver(this);//可以不再此处销毁
}

下面的一个广播接受器实现了接收点击Home键发出的广播(点击Home键发出的广播必须使用静态注册才可以监听到)

 /**
* 本篇主要实现了对Home键的监听
*
* @author Administrator
*
*/
public class SortedBroadcast extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
// 接收自定义的广播
if (intent.getAction().equals("com.zhj.test")) {
String str = intent.getStringExtra("msg");// 接收发送广播的时候传递的参数
Toast.makeText(context, "receiver2:" + str, Toast.LENGTH_SHORT)
.show();
abortBroadcast();
} // 对Home键的监听
if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra("reason");
if (reason.equals("homekey")) {
Toast.makeText(context, "短按Home键", Toast.LENGTH_SHORT).show();
} else if (reason.equals("recentapps")) {
Toast.makeText(context, "长按/双击 Home键", Toast.LENGTH_SHORT)
.show();
} else if (reason.equals("lock")) {
Toast.makeText(context, "锁屏", Toast.LENGTH_SHORT).show();
} else if (reason.equals("assist")) {
Toast.makeText(context, "未知" + reason, Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(context, "event:" + reason, Toast.LENGTH_SHORT)
.show();
}
abortBroadcast();//终止广播的传递(仅在接收有序广播的时候有效)
}
}
}

通过广播启动一个activity,当我们通过一个广播启动activity的时候,程序强行停止,报错

经过一番查找,发现通过以下的方式可以启动:

    @Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent intent2 = new Intent(context, StartActivity.class);
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent2);
}

=

Broadcast详解的更多相关文章

  1. Android随笔之——Android广播机制Broadcast详解

    在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理.这个广播跟我们传统意义中的电台广播有些相似之处.之所以叫做广播,就 ...

  2. 17_Android中Broadcast详解(有序广播,无序广播)最终广播,Bundle传递参数,传递参数的时候指定权限

     1  Broadcast是Android中的四大组件之一,他的用途很大,比如系统的一些广播:电量低.开机.锁屏等一些操作都会发送一个广播. 2  广播被分为两种不同的类型:"普通广播( ...

  3. angularjs事件通信$on,$emit,$broadcast详解

    公司项目开发用的是angularjs,关于事件通讯一直用的是EventBus,直到上周写一个小组件懒得引用EventBus时,想到用angularjs自带的事件通信时,结果很尴尬的忘记原生方法单词怎么 ...

  4. Android中的广播Broadcast详解

    今天来看一下Android中的广播机制,我们知道广播Broadcast是Android中的四大组件之一,可见他的重要性了,当然它的用途也很大的,比如一些系统的广播:电量低.开机.锁屏等一些操作都会发送 ...

  5. Android随笔之——闹钟制作铺垫之AlarmManager详解

    说实话,之前写的两篇博客Android广播机制Broadcast详解.Android时间.日期相关类和方法以及现在要写的,都算是为之后要写的闹钟应用做铺垫,有兴趣的话,大家可以去看看前两篇博客. 一. ...

  6. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  7. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  8. Android消息传递之EventBus 3.0使用详解

    前言: 前面两篇不仅学习了子线程与UI主线程之间的通信方式,也学习了如何实现组件之间通信,基于前面的知识我们今天来分析一下EventBus是如何管理事件总线的,EventBus到底是不是最佳方案?学习 ...

  9. 手游录屏直播技术详解 | 直播 SDK 性能优化实践

    在上期<直播推流端弱网优化策略 >中,我们介绍了直播推流端是如何优化的.本期,将介绍手游直播中录屏的实现方式. 直播经过一年左右的快速发展,衍生出越来越丰富的业务形式,也覆盖越来越广的应用 ...

随机推荐

  1. Ubuntu server 14.04 交叉编译Unicorn-engine

    Ubuntu server 14.04 交叉编译Unicorn-engine 编译的过程基本上按照的是unicorn/COMPILE-WINDOWS.md描述的进行编译的,不过还是改了一些地方.在Ub ...

  2. mysql配置的讲解 mysql的root密码重置 mysql的登录

    一,MySQL配置的讲解 port  默认mysql端口 socket  用于服务器端和客户端通信的套连接文字 skip-locking 取消文件系统的外部锁 key_buffer_size  索引缓 ...

  3. sublime 快键

    Keyboard Shortcuts - Windows/Linux Warning This topic is a draft and may contain wrong information. ...

  4. Web App 图片上传编辑器

    使用cropper.jqueryUpload插件.Jquery.src-dataurl-canvas-blob文件. @{ ViewBag.Title = "更新头像"; Layo ...

  5. .Net中如何使用MySql连接池

    提供一份官方的译文.翻译也挺辛苦的!! 6.4 Using Connector/Net with Connection Pooling 6.4在Connector/Net中使用连接池 The Conn ...

  6. SQL使用记录

    Q:怎么删掉sql server登录时的用户名?(仅仅是删掉那个登录时的提示) A:先关闭数据库登录引擎,然后删除:%AppData%\Microsoft\Microsoft SQL Server\1 ...

  7. [原创]Windows下Google V8 javascript引擎编译

    项目用到将v8嵌入到C++的情况,公司没时间研究,只有在家研究,编译过程一堆坑.记录一下. 网上百度的都是基于vs2010,或者早版本的v8编译,最新版本应该使用vs2013\vs2015.本文介绍的 ...

  8. linux 查看目录名称的方法

    1. ls -d * 2. grep查找以'/'结尾的,也就是目录 ls -F | grep '/$'

  9. Candy Bags

    读懂了题就会发现这是个超级大水题 Description Gerald has n younger brothers and their number happens to be even. One ...

  10. margin-top失效及解决办法

    现象:当两个空的块级元素嵌套时,如果内部的块设置有margin-top属性,而且父元素没有下边解决方法所述的特征,那么内部块的margin-top属性会绑架父元素(即将margin-top传递凌驾给了 ...