转载请标明出处: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. 钉钉开放平台demo调试异常问题解决:hostname in certificate didn't match

    今天研究钉钉的开放平台,结果一个demo整了半天,这帮助系统写的也很难懂.遇到两个问题: 1.首先是执行demo时报unable to find valid certification path to ...

  2. 如果你发现mysql的外键约束不管用了

    不知为何我机子上的mysql竟然默认关闭外键约束,导致我试了好多遍都可以插入非法值,以下语句可以开启约束 SET foreign_key_checks = 1; (0则关闭) 备忘

  3. 用java开发微信公众号:公众号接入和access_token管理(二)

    本文为原创,原始地址为http://www.cnblogs.com/fengzheng/p/5027630.html 上一篇说了微信开发的准备工作,准备工作完成之后,就要开始步入正题了.其实微信公众号 ...

  4. Android RecyclerView 实现支付宝首页效果

    Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...

  5. Java笔记——Java8特性之Lambda、方法引用和Streams

    Java8已经推出了好一段时间了,而掌握Java8的新特性也是必要的,如果要进行Spring开发,那么可以发现Spring的官网已经全部使用Java8来编写示例代码了,所以,不学就看不懂. 这里涉及三 ...

  6. 原生ajax实现登录(一部分代码)

        <script type="text/javascript">          function ajax() {          //先声明一个异步请求对 ...

  7. 学习WCF入门的第一个实例

    一.概述 WCF说白了就是一个基于终结点的通信手段!就是Service端提供一定的功能实现,然后暴露出一个或多个终结点,Client端调用Service端的功能(可以理解为调用一个函数),那么Clie ...

  8. 前端学HTTP之基本认证

    前面的话 人们用Web进行私人事务处理,访问私有的数据.通过Web可以很方便地访问这些信息,但仅仅是方便访问还是不够的.我们要保证只有特定的人能看到我们的敏感信息并且能够执行我们的特权事务 服务器需要 ...

  9. 浅析MySQL复制

    MySQL的复制是基于binlog来实现的. 流程如下 涉及到三个线程,主库的DUMP线程,从库的IO线程和SQL线程. 1. 主库将所有操作都记录到binlog中.当复制开启时,主库的DUMP线程根 ...

  10. 【NLP】揭秘马尔可夫模型神秘面纱系列文章(二)

    马尔可夫模型与隐马尔可夫模型 作者:白宁超 2016年7月11日15:31:11 摘要:最早接触马尔可夫模型的定义源于吴军先生<数学之美>一书,起初觉得深奥难懂且无什么用场.直到学习自然语 ...