转载请标明出处:http://www.cnblogs.com/zhaoyanjun/p/6048369.html

本文出自【赵彦军的博客】

前言

在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。我们拿广播电台来做个比方。我们平常使用收音机收音是这样的:许许多多不同的广播电台通过特定的频率来发送他们的内容,而我们用户只需要将频率调成和广播电台的一样就可以收听他们的内容了。Android中的广播机制就和这个差不多的道理。

BroadcastReceiver安全问题

BroadcastReceiver设计的初衷是从全局考虑可以方便应用程序和系统、应用程序之间、应用程序内的通信,所以对单个应用程序而言BroadcastReceiver是存在安全性问题的(恶意程序脚本不断的去发送你所接收的广播)。为了解决这个问题LocalBroadcastManager就应运而生了。

LocalBroadcastManager

LocalBroadcastManager是Android Support包提供了一个工具,用于在同一个应用内的不同组件间发送Broadcast。LocalBroadcastManager也称为局部通知管理器,这种通知的好处是安全性高,效率也高,适合局部通信,可以用来代替Handler更新UI

  • 好处:

1、因广播数据在本应用范围内传播,你不用担心隐私数据泄露的问题。

2、不用担心别的应用伪造广播,造成安全隐患。

3、相比在系统内发送全局广播,它更高效。

LocalBroadcastManager用法

  • LocalBroadcastManager对象的创建

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;

  • 注册广播接收器

LocalBroadcastManager.registerReceiver( broadcastReceiver , intentFilter );

  • 发送广播

LocalBroadcastManager.sendBroadcast( intent ) ;

  • 取消注册广播接收器

LocalBroadcastManager.unregisterReceiver( broadcastReceiver );

LocalBroadcastManager部分源码解析

    private static LocalBroadcastManager mInstance;

    public static LocalBroadcastManager getInstance(Context context) {
synchronized (mLock) {
if (mInstance == null) {
mInstance = new LocalBroadcastManager(context.getApplicationContext());
}
return mInstance;
}
} private LocalBroadcastManager(Context context) {
mAppContext = context;
mHandler = new Handler(context.getMainLooper()) { @Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_EXEC_PENDING_BROADCASTS:
executePendingBroadcasts();
break;
default:
super.handleMessage(msg);
}
}
};
}

从这个部分源码可以看出两点:

  • 在获取LocalBroadcastManager对象实例的时候,这里用了单例模式。并且把外部传进来的Context 转化成了ApplicationContext,有效的避免了当前Context的内存泄漏的问题。这一点我们在设计单例模式框架的时候是值得学习的,看源码可以学习到很多东西。

  • 在LocalBroadcastManager构造函数中创建了一个Handler.可见 LocalBroadcastManager 的本质上是通过Handler机制发送和接收消息的。

  • 在创建Handler的时候,用了 context.getMainLooper() , 说明这个Handler是在Android 主线程中创建的,广播接收器的接收消息的时候会在Android 主线程,所以我们决不能在广播接收器里面做耗时操作,以免阻塞UI。

一个小例子

package com.app;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log; public class MainActivity extends AppCompatActivity { private LocalBroadcastManager localBroadcastManager ;
private MyBroadcastReceiver broadcastReceiver ;
private IntentFilter intentFilter ; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //注册广播接收器
localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;
broadcastReceiver = new MyBroadcastReceiver() ;
intentFilter = new IntentFilter( "myaction") ;
localBroadcastManager.registerReceiver( broadcastReceiver , intentFilter ); //在主线程发送广播
Intent intent = new Intent( "myaction" ) ;
intent.putExtra( "data" , "主线程发过来的消息" ) ;
localBroadcastManager.sendBroadcast( intent ) ; new Thread(new Runnable() {
@Override
public void run() {
//在子线程发送广播
Intent intent = new Intent( "myaction" ) ;
intent.putExtra( "data" , "子线程发过来的消息" ) ;
localBroadcastManager.sendBroadcast( intent ) ;
}
}).start(); ; } private class MyBroadcastReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction() ;
if ( "myaction".equals( action )){
Log.d( "tttt 消息:" + intent.getStringExtra( "data" ) , "线程: " + Thread.currentThread().getName() ) ;
}
}
} @Override
protected void onDestroy() {
super.onDestroy(); //取消注册广播,防止内存泄漏
localBroadcastManager.unregisterReceiver( broadcastReceiver );
}
}

运行结果

D/tttt 消息:主线程发过来的消息: 线程: main
D/tttt 消息:子线程发过来的消息: 线程: main

可以看出,广播接收器的onReceive方法运行在主线程。

注意事项

虽然LocalBroadcastManager也通过BroadcastReceiver 来接收消息,但是他们两个之间还是有很多区别的。

  • LocalBroadcastManager注册广播只能通过代码注册的方式。传统的广播可以通过代码和xml两种方式注册。
  • LocalBroadcastManager注册广播后,一定要记得取消监听。这一步可以有效的解决内存泄漏的问题。
  • LocalBroadcastManager注册的广播,您在发送广播的时候务必使用LocalBroadcastManager.sendBroadcast(intent); 否则您接收不到广播。传统的发送广播的方法:context.sendBroadcast( intent );

Android LocalBroadcastManager 的使用总结的更多相关文章

  1. Android LocalBroadcastManager解析

    阿里巴巴Android开发手册[强制]避免使用隐式 Intent 广播敏感信息,信息可能被其他注册了对应BroadcastReceiver 的 App 接收.说明:通过 Context#sendBro ...

  2. Android LocalBroadcastManager 与 BroadcastReceiver

    Android中BroadcastReceiver主要用途有 发送通知,更新UI或者数据,应用程序间相互通信,监听系统状态(比如开机,网络等) Android中发送广播的方式: 普通广播:无论优先级大 ...

  3. [Android Pro] Android 之使用LocalBroadcastManager解决BroadcastReceiver安全问题

    参考博客: http://blog.csdn.net/t12x3456/article/details/9256609 http://blog.csdn.net/lihenair/article/de ...

  4. Android 中LocalBroadcastManager的使用方式

    Android 中LocalBroadcastManager的使用方式 在android-support-v4.jar中引入了LocalBroadcastManager,称为局部通知管理器,这种通知的 ...

  5. Android 之使用LocalBroadcastManager解决BroadcastReceiver安全问题

    在Android系统中,BroadcastReceiver的设计初衷就是从全局考虑的,可以方便应用程序和系统.应用程序之间.应用程序内的通信,所以对单个应用程序而言BroadcastReceiver是 ...

  6. 本地广播 localBroadcastManager Android

    使用localBroadcastManager发出的广播只能在本应用程序的内部进行传递. App应用内广播可理解为一种局部广播,广播的发送者和接收者都同属于一个App. 相比于全局广播(普通广播),A ...

  7. Android英文文档翻译系列(6)——LocalBroadcastManager

    public class LocalBroadcastManager extends Object java.lang.Object    ↳ android.support.v4.content.L ...

  8. (转)Android 中LocalBroadcastManager的使用方式

    发表于2个月前(2014-11-03 22:05)   阅读(37) | 评论(0) 0人收藏此文章, 我要收藏 赞0 1月10日 #长沙# OSC 源创会第32期开始报名 摘要 android中广播 ...

  9. android中LocalBroadcastManager的使用

    今天遇到一个acitivity之间通信的问题,因为我们是用TabActivity包裹了Activity(我们称之为A).所以这两个Activity是同一时候存在的.当在TabActivity中启动其它 ...

随机推荐

  1. 2015微软MVP全球峰会见闻

    2015.10.31-2015.11.8 一周的时间完成微软MVP全球峰会旅程,这一周在不断的倒时差,行程安排非常的紧张,还好和大家请假了没有更新微信公众号,今天开始继续更新微信公众号,开始新的旅程, ...

  2. ABP文档 - Web Api 控制器

    文档目录 本节内容: 简介 AbpApiController 基类 本地化 其它 过滤 审计日志 授权 防伪造过滤 工作单元 结果包装和异常处理 结果缓存 验证 模块绑定器 简介 通过Abp.Web. ...

  3. Atitit ABI FFI 的区别与联系 attilax总结

    Atitit ABI FFI 的区别与联系 attilax总结 FFI stands for Foreign Function Interface. A foreign function interf ...

  4. CSS系列目录

    1.  在HTML中引入CSS的方法 2.  CSS选择器 2.1 CSS3新增选择器 3.  CSS的继承与层叠特性 4.  CSS中盒子模型 5.  CSS中盒子之间的关系 6.  CSS中盒子的 ...

  5. 【WCF】自定义地址头的筛选器

    前面的文章中,老周已向大伙伴们介绍了如何在终结点上使用地址头,只要服务是沿着该终结点调用的,那么每一次调用都会自动把地址头插入到SOAP消息的Header列表中. 而通过前一篇文章中的示例,大家也看到 ...

  6. H5 Notes:PostMessage Cross-Origin Communication

    Javascript中要实现跨域通信,主要有window.name,jsonp,document.domain,cors等方法.不过在H5中有一种新的方法postMessage可以安全实现跨域通信,并 ...

  7. [C#] 走进异步编程的世界 - 剖析异步方法(上)

    走进异步编程的世界 - 剖析异步方法(上) 序 这是上篇<走进异步编程的世界 - 开始接触 async/await 异步编程>(入门)的第二章内容,主要是与大家共同深入探讨下异步方法. 本 ...

  8. ASP.NET 页面禁止被 iframe 框架引用

    两个站点: a.sample.com b.sample.com a.sample.com 站点中的一段示例 JS 代码: var iframe = document.createElement(&qu ...

  9. NLP&数据挖掘基础知识

    Basis(基础): SSE(Sum of Squared Error, 平方误差和) SAE(Sum of Absolute Error, 绝对误差和) SRE(Sum of Relative Er ...

  10. 单机静默安装GI软件并创建ASM实例和ASM磁盘组

    环境:RHEL 6.4 + Oracle 11.2.0.4 需求:单机静默安装GI软件并创建ASM实例和ASM磁盘组,为后续迁移数据库文件到ASM做准备 1. 安装配置GI软件 2. 创建ASM实例 ...