Android LocalBroadcastManager 的使用总结

时间:2021-08-17 09:41:14

转载请标明出处: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. 主流浏览器css兼容问题的总结

    最近又搞了一波网站的兼容,由于要求ie浏览器还是要兼容到ie8,所以调起来还是各种蛋疼. 现在就post一些做兼容的总结,可能不够全面,但是可以告诉大家如何避过一些坑.主要测试了chrome,fire ...

  2. AtCoder Grand Contest 008 A

    Problem Statement Snuke has a calculator. It has a display and two buttons. Initially, the display s ...

  3. gulp插件autoprefixer

    gulp的autoprefixer插件可以根据我们的设置帮助我们自动补全浏览器的前缀(如:-moz.-ms.-webkit.-o) 1)首先安装gulp,不知道怎么安装请看这里 2)安装autopre ...

  4. 低功耗蓝牙4.0BLE编程-nrf51822开发(1)

    为了省钱,也为了提高手动能力,只买了块核心板,仿真器用的是旧的jinkv7,自己搭扩展板,DIY就这样开始了. 买这块之前做了些调查,最终选定了nrf51822,功耗低,性能强,开发难度小,虽然比TI ...

  5. inline-block 前世今生

    曾几何时,display:inline-block 已经深入「大街小巷」,随处可见 「display:inline-block; *display:inline; *zoom:1; 」这样的代码.如今 ...

  6. java含多个包的命令行下执行

    C:\Users\liyang\Desktop\BAE\Baidu-BCS-SDK-Java-1.4.5>java -classpath(可以cp简写) bcs-sdk-java_1.4.5.j ...

  7. H5小内容(六)

    Web Worker   基本内容     单线程与多线程       Worker可以模拟多线程的效果     定义 - 运行在后台的javascript     注意 - 不能使用DOM      ...

  8. WebStorm里使用注意点

    归纳一些我在使用webstorm里遇到的问题: 1.问题:文件出现红线,如图 解决方案:可能是由于语言版本的问题,改一下版本试试 2.快捷键:http://www.cnblogs.com/yeming ...

  9. 干货,分享一次完整的CentOS升级内核脚本。

    一.安装常用包 yum install wget vim screen net-tools lrzsz -y wget -O /etc/yum.repos.d/epel.repo http://mir ...

  10. Golang微服务:Micro Trace使用opentracing jaeger

    trace Micro通过Wrapper实现了三种trace接口,aswxray,opencensus,opentracing,这里主要关注opentracing,opentracing已成为行业标准 ...