BroadcastReceiver基础总结

BroadcastReceiver是Android四大组件之一,主要负责接收系统或其他程序发出的广播,在开发中,通常用做事件驱动的起源,比如开机就要开启一个程序,有网络就要开始下载资源,安装或卸载包了,就要跟新UI等等。以下就对这个组件总结我自己的理解:

BroadcastReceiver的生命周期

BroadcastReceiver的生命周期很短,当系统或其他程序发出广播的时候,Android系统的包管理对象就会检查所有已安装的包中的配置文件有没有匹配的action,如果有,并且可以接收,那么就调用这个BroadcastReceiver,获取BroadcastReceiver对象,然后执行onReceiver(),这个时候BroadcastReceiver对象就没有了,被摧毁了,所有说BroadcastReceiver的生命周期是非常短的。切记,在onReveiver()中不能做比较耗时的操作,不然会弹出ANR对话框。如果真的要完成耗时的工作的话,可以交给Service去完成。另外,onReceiver()中也不能用子线程来操作,大家都知道,当父进程被杀死后,它的子进程也会被杀死,所以,这是很不安全的做法。

按活动模式来分类BroadcastReceiver

常驻型广播:不随Activity的生命周期而改变,即使Activity被摧毁了,这个BroadcastReceiver依然能够接受广播,一般在配置文件中定义。

非常驻型广播:随着Activity的生命周期而改变,在程序中定义。

到底用哪一种比较好,这里要看程序的需求。比如,需要捕捉开机事件就启动一个包,那么,这个最好是用常驻型广播。比如,系统设置的应用程序管理界面中,监听是否有包被安装,以便跟新UI,这里最好是使用非常驻型广播好。

按优先级来分类BroadcastReceiver

有序广播:接收广播的时候有优先级,优先级在receiver中的android:property属性中指定,数值越大优先级越高。其优先级范围是[-1000,1000],这里需要注意两点。第一,有序广播可以中断广播的继续传送,中断之后,排列在这个广播接收器之后的接收器就接收不到该广播了,只需要在这个广播接收器中的onReceiver()中使用abortBroadcast()方法。第二,接收者可以在接收过程中向即将收到广播的接收器传递数据,这里传递数据用Bundle。代码说明:

前面的接收者可以通过setResultExtras(Bundle)存放数据,下一个接收者可以通过

Bundle mBundle =getResultExtras(true) ;来接收数据。

普通广播:这些广播接收器在接收广播的时候是无序的,当然,谁也没有权利来中断这个广播,因为它不存在接收队列!

现在来看看代码,首先总结下注册广播的方法:

第一种方法:在配置文件中注册广播(接收apk包被安装了的广播)

首先定义一个类继承BroadcastReceiver,并且覆写onReceiver方法

package dxd.android.test;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log; public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("android.intent.action.PACKAGE_ADDED")){
Log.e("MyReceiver","安装了包"+intent.getDataString());
}
}
}

然后,在配置文件AndroidManifest.xml文件中添加receiver节点

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dxd.android.test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" /> <application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MyBroadcastReceiverActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <receiver android:name=".MyReceiver">
<intent-filter >
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<data android:scheme="package" />
<!-- 这句一定要加 -->
</intent-filter>
</receiver>
</application>
</manifest>

还有一个主Activity类就没有写出来了,在该类中就根本没有调用任何接收器的方法。

第二种:在程序中注册广播接收器(接收apk被安装了的广播)

在刚才的代码之上,只需要在主Activity中添加注册和解除广播接收器的代码。

package dxd.android.test;

import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle; public class MyBroadcastReceiverActivity extends Activity {
MyReceiver receiver = new MyReceiver();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PACKAGE_ADDED") ;
registerReceiver(receiver, filter) ;
} @Override
protected void onDestroy() {
unregisterReceiver(receiver) ;
super.onDestroy();
}
}

凡是广播,就逃不出这两种注册方式!可以看到,第一种在配置文件注册的广播就是常驻型广播,它并不受Activity的生命周期的控制,第二种在程序中注册的广播是非常驻型广播,当Activity被摧毁时,这个广播就注销了。这里,说明一下,当有这两种方式共同存在的时候,会以第二种程序中注册的广播为准。 好,之前举例都是接收的系统的广播,那么
如何接收自己定义的广播呢?

首先,要明天自己需要发送什么广播,这里就以收到广播之后,去跳转到一个activity为例,广播为:“dxd.android.test.START_ACTIVITY”,名字是自己定义的!随意修改,但是要保持一致。首先还是要写一个类继承自BroadcastReceiver:

package dxd.android.test;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log; public class DIYReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction() ;
Log.e("DIYReceiver", "action = " + action) ;
if(action.equals("dxd.android.test.START_ACTIVITY")){
Intent intentTo = new Intent(context,NextActivity.class) ;
intentTo.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 没有在activity中启动,必须加这句。
context.startActivity(intentTo) ;
}
}
}

然后
,在配置文件中书写receiver标签

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dxd.android.test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" /> <application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".DIYBroadcastReceiverActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <activity android:name=".NextActivity"></activity> <receiver android:name=".DIYReceiver" <intent-filter>
<action android:name="dxd.android.test.START_ACTIVITY"/>
</intent-filter>
</receiver>
</application>
</manifest>

现在在程序中发送自己定义的广播:

package dxd.android.test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; public class DIYBroadcastReceiverActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); Button but = (Button)findViewById(R.id.but); but.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DIYBroadcastReceiverActivity.this ,DIYReceiver.class);
intent.setAction("dxd.android.test.START_ACTIVITY");
sendBroadcast(intent);
}
});
}
}

可以看到,在DIYBroadcastReceiverActivity页面中有一个按钮,当点击按钮之后就会发出广播,当广播接收器接收到广播之后,就会开始跳转页面。

有权限的广播

有时发送者要求广播接收器需要有权限才能接收广播,那么这时该怎么定义呢,其实就只需要添加一个权限即可,这里跟之前发送广播的方法有点小小的不通。看代码

package dxd.android.test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; public class DIYBroadcastReceiverActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); Button but = (Button)findViewById(R.id.but); but.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DIYBroadcastReceiverActivity.this ,DIYReceiver.class);
intent.setAction("dxd.android.test.START_ACTIVITY");
sendBroadcast(intent,"dxd.android.test.permission.receiver");// 这里发送广播的方式不一样
}
});
} @Override
protected void onDestroy() {
super.onDestroy();
} }

自己写的Receiver几乎跟之前的是一样的

public class DIYReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction() ;
Log.e("DIYReceiver", "action = " + action) ;
if(action.equals("dxd.android.test.START_ACTIVITY")){
Intent intentTo = new Intent(context,NextActivity.class) ;
intentTo.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 没有在activity中启动,必须加这句。
context.startActivity(intentTo) ;
}
}
}

主要看配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dxd.android.test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" /> <application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".DIYBroadcastReceiverActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <activity android:name=".NextActivity"></activity> <receiver android:name=".DIYReceiver" >
<intent-filter>
<action android:name="dxd.android.test.START_ACTIVITY"/>
</intent-filter> </receiver> </application> <permission android:name="dxd.android.test.permission.receiver"></permission>
<uses-permission android:name="dxd.android.test.permission.receiver"/>
</manifest>

综合判断起来,就是sendBroadcast(intent,permission),和在配置文件中增加了一个权限的声明,和添加这个权限!

到此为止,就只有粘性广播没有总结。之后搞清楚了才写。

BroadcastReceiver基础总结的更多相关文章

  1. 四大组件之BroadcastReceiver基础

    1. 系统广播 1.1 动态注册   (1)创建自定义接收器类继承自BroadcaseReceiver,实现onReceive()方法,对接收到的广播的逻辑处理就是写在这个函数中的.   (2)实例化 ...

  2. 【转】 Pro Android学习笔记(九七):BroadcastReceiver(1):基础小例子

    目录(?)[-] 基础小例子 发送Broadcast intent 运行情况 应用间的广播 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog ...

  3. Android基础新手教程——4.3.1 BroadcastReceiver牛刀小试

    Android基础新手教程--4.3.1 BroadcastReceiver牛刀小试 标签(空格分隔): Android基础新手教程 本节引言 本节我们将来学习Android四大组件中的第三个:Bro ...

  4. Android基础新手教程——4.3.2 BroadcastReceiver庖丁解牛

    Android基础新手教程--4.3.2 BroadcastReceiver庖丁解牛 标签(空格分隔): Android基础新手教程 本节引言: 上节我们对BroadcastReceiver已经有了一 ...

  5. 基础总结篇之五:BroadcastReceiver应用详解

    問渠那得清如許?為有源頭活水來.南宋.朱熹<觀書有感> 据说程序员是最爱学习的群体,IT男都知道,这个行业日新月异,必须不断地学习新知识,不断地为自己注入新鲜的血液,才能使自己跟上技术的步 ...

  6. Android应用开发基础篇(7)-----BroadcastReceiver

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/22/2363644.html 一.概述 BroadcastReceiver,意思就是广播信息接收 ...

  7. 基础总结篇之五:BroadcastReceiver应用具体解释

    問渠那得清如許?為有源頭活水來.南宋.朱熹<觀書有感> 据说程序猿是最爱学习的群体,IT男都知道,这个行业日新月异,必须不断地学习新知识,不断地为自己注入新奇的血液,才干使自己跟上技术的步 ...

  8. Android基础总结(七)BroadcastReceiver

    广播(掌握) 广播的概念 现实:电台通过发送广播发布消息,买个收音机,就能收听 Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件. Andro ...

  9. <Android 基础(二)> BroadcastReceiver

    介绍 BroadcastReceiver:广播接收者,很形象,广播发送,类比生活中的广播,有能力听得到的都可以介绍到这个信息,然后在大脑中反映.对应到Android中就是SendBroadcast和o ...

随机推荐

  1. iOS根据获取的月和日星座名称

    /** * 依据月和日的下标获取星座名 * * @param monthIndex 月的下标 * @param dayIndex 日的下标 * * @return 星座名 */ - (NSString ...

  2. node.js的npm安装

    我不打算引进node.js的npm安装,但发现node.js通过管理一些包npm实现,或给一个简短的npm. 1.npm什么        npm是一个node包管理和分发工具,已经成为了非官方的公布 ...

  3. Jenkins + robot framework自动发送邮件报告

    一.Jenkins安装插件 进入系统管理—插件管理—可选插件下安装以下插件Email-ext plugin.Email-ext Template Plugin. 安装完如下: 二.系统设置 1.设置系 ...

  4. order by使用方法

    1.ORDER BY 中关于NULL的处理 缺省处理,Oracle在Order by 时觉得null是最大值,所以假设是ASC升序则排在最后,DESC降序则排在最前. 当然,你也能够使用nulls f ...

  5. C--指针数组

    一个变量有一个地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,他们都有相应的地址,所谓数组的指针是指数组的其实地址,数组元素的指针是数组元素的地址. 一个数组是有连续的一块内存单元组成 ...

  6. HHVM Installation and Configuration(HHVM 安装及配置)

    Installation and Configuration¶ General Installation Considerations Installation on Linux systems Ub ...

  7. Ejb in action(七)——message与JMS

    我们扩大MDBs学前,我们需要理解message(新闻)与JMS(Java Message Service)的概念. 我们在Java EE中谈论消息,实际上就是意味着实现一个松耦合的过程.系统组件之间 ...

  8. Linux 查看和删除进程

    1. 在 LINUX 命令平台输入 1-2 个字符后按 Tab 键会自动补全后面的部分(前提是要有这个东西,例如在装了 tomcat 的前提下, 输入 tomcat 的 to 按 tab).2. ps ...

  9. JavaScript插件化开发

    大熊君JavaScript插件化开发 一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得昨天的那篇文章吗------这个系列的开篇(第一季).主要讲述了以“jQuery的方式如何开发插件”, 那 ...

  10. EA强大的绘图工具---设计数据库表格

    关于EA这个优秀的软件是从师哥哪里听来的,自己瞎点了点,感觉也没什么.近期和和智福加上一个师哥合作敲机房收费系统时,想到之前听人说EA非常强大,便随便找了找关于EA使用的帮助手冊.果然惊喜-- 如题, ...