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. Floodlight Controller 路线原则

         SDN的出现能够使得各种复杂的路由协议从原本的Device OS中剥离出来,放在SDN Controller中.Controller用一种简单的协议来和全部的Router进行通信.就能够获得 ...

  2. Spring框架和MVC原理

    Spring框架和MVC原理 目录 Spring框架 SpringMVC工作原理 参考资料 回到顶部 Spring框架 Spring当前框架有20个jar包,大致可以分为6大模块: Core Cont ...

  3. linux_安装_安装编译phantomjs 2.0的方法_转

    项目中要对数据公式webkit渲染,phantmjs 2.0的效果好比1.9好不少. 安装过程中 坑比较多. 转载文章: phantomjs 2.0最新版的官方不提供编译好的文件下载,只能自己编译,有 ...

  4. mysql_常用命令

    1: 以指定编码创建数据库 CREATE DATABASE `search_data` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

  5. 2014年最新的辛星html、css教程打包公布了,免积分,纯PDF(还有PHP奥)

    首先说一下,这个教程是我的全部的博客的精华,我整理了两天之后才做出的这个pdf文档,累死我了,以下免积分给大家,希望大家可以不吝指正,提出它的一些不足什么的,谢谢啦: 以下就是它的下载地址了:2014 ...

  6. 华为机试 之 joseph环

    一:首先科普一下约瑟夫问题的数学方法 (1)  不管是用list实现还是用vector实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比較烦,并且时间复杂度高达O(nm),当n,m很大(比如上百 ...

  7. Linux下一个C基本的编程----写进Blog在那之前

    展望2周的实习吧. 各种酸甜苦辣.由于公司只是广告.毛承保让我去.严重的歧视.想也想开,争夺.结果让它成为.还是把它写自己的学习经验,我有同样的希望和迷茫的同学.少走一点弯路.行.切入正题: 一.參考 ...

  8. MVC Bootstrap Helpers

    ASP.NET MVC Bootstrap Helpers   阅读目录 序言 内置的HTML Helpers 创建自定义的Helpers 使用静态方法创建Helpers 使用扩展方法创建Helper ...

  9. js中从blob提取二进制

    文章结构: 一.所遇到的问题 二.解决方法 一. 服务器端通过websocket向浏览器端传输图片(二进制),需要根据不同的图片把图片显示在不同的位置,可行的一个方法是先把图片转化成二进制数组,再把二 ...

  10. C#操作 Advantage Database Server 数据库

    相关下载 http://devzone.advantagedatabase.com/dz/content.aspx?key=31 1.安装数据库: Advantage Database Server ...