Android 动态广播生命周期,Android必知必会的四大组件 -- Broadcast Receiver篇

9be26fe79c0a0fb06e333aae1729e522.png

前言

广播,在我们的应用中起着一个非常重要的角色。就比如说我们经常使用的Intent、IntentFilter,就有着广播的作用。

在我的Android工具包项目中就集成了网络广播的动态注册。

目录

思维导图

077d0561f74f1a46c3f01ac97dc99ff0.png

生命周期

因为没有直接的图示可以上,而且Broadcast中并没有onCreate、onDestroy这样方法,只能通过官方文档验证。c4b5011723f73ae6847b7604b763aedf.png

图中的圈红框的加粗文字大概意思就是,使用静态广播进行注册,那么每接受到一次信息,他就不复存在了,也就是需要重建。其它方式构建的生命周期,与关联的Activity中的具体操作相关。

在Android 8.0以后已经不在支持静态广播了

两种广播

public class NetworkReceiver extends BroadcastReceiver{

@Override

public void onReceive(Context context, Intent intent){

if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION) && App.getInstance() != null) {

App.getInstance().notifyObservers(isNetConnected(context));

}

}

}

复制代码

虽然是两种广播形式,但是他们同样要干一件事情,就是继承BroadcastReceiver,并重写onReceive()方法。

全局广播

这个广播同样可以使用在应用内,但是这种广播的安全性有待质疑。

// 消息传递

sendBroadcast(Intent);

复制代码静态广播注册

复制代码动态广播注册

和静态广播不同的地方,动态广播注册完以后需要进行注销操作。

// 注册

networkReceiver = new NetworkReceiver();

IntentFilter intentFilter = new IntentFilter();

intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");

registerReceiver(networkReceiver, intentFilter);

// 注销(如果没有注销,将会发生内存泄漏)

unregisterReceiver(networkReceiver);

复制代码

应用内广播

优点:

发送的广播只会在自己的App内传播,不会泄漏给其他App,保障了数据的安全性。

无法接受到其他App的广播,也就省去各种麻烦事。

相较于全局广播效率更高。

使用方法

//注册

networkReceiver = new NetworkReceiver();

localBroadcastManager = LocalBroadcastManager.getInstance(this); // --> 以单例模式进行创建

localBroadcastManager.registerReceiver(networkReceiver, new IntentFilter("需要去过滤的信息"));

// 发送消息

localBroadcastManager.sendBroadcast(Intent);

// 注销

localBroadcastManager.unregisterReceiver(networkReceiver);

复制代码

LocalBroadcastManager源码导读

为什么要导读LocalBroadcastManager源码呢?

其实是想让读者们知道LocalBroadcastManager使用并不是Binder机制来完成通信的。

getInstance()

public static LocalBroadcastManager getInstance(@NonNull Context context){

synchronized (mLock) {

if (mInstance == null) {

mInstance = new LocalBroadcastManager(context.getApplicationContext()); // 1 -->

}

return mInstance;

}

}

// 由注释1直接调用的方法

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);

}

}

};

}

复制代码

那这里就是很清楚的知道,这是一个以DCL的方式,来直接完成对单例的创建,而在构造函数中,定义了一个Handler。

那我们就来做一个猜测,我们在应用内的广播本质其实是基于一个Handler的一异步传输机制。为了验证!!我们就需要去了解他的sendBroadcast(Intent)方法。

sendBroadcast(Intent)

public boolean sendBroadcast(@NonNull Intent intent){

synchronized (mReceivers) {

// 拿到传递过来的Intent中保存的数据

final String action = intent.getAction();

final String type = intent.resolveTypeIfNeeded(

mAppContext.getContentResolver());

final Uri data = intent.getData();

final String scheme = intent.getScheme();

final Set categories = intent.getCategories();

// 。。。。。

// 获取配置的Action

ArrayList entries = mActions.get(intent.getAction());

if (entries != null) {

if (debug) Log.v(TAG, "Action list: " + entries);

ArrayList receivers = null;

// 。。。。。 对变量receivers的一些列操作。

// 存在接受对象时,将数据通过Handler的方式传递出去。

if (receivers != null) {

for (int i=0; i

receivers.get(i).broadcasting = false;

}

mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));

if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {

mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);

}

return true;

}

}

}

return false;

}

复制代码

通过代码已经成功验证了,其实LocalBroadcast最终基于的数据传输机制就是我们的Handler,这就是和应用间广播最大的不同之处了。

总结

动态广播和静态广播的区别?

静态广播:广播一直存在,消耗资源较大,耗电量大。

动态广播:广播的生命周期较为灵活,资源消耗少。响应速度快于静态广播。

广播同样会引发ANR的惨状,广播的耗时操作时长不允许超过10s。而且广播内一般也不会像Service和Activity一样会使用Thread来完成我们的耗时操作。

全局和应用内的广播两者的注册方式其实相似,但是针对的场景不同。如果需要网络、电池等服务,你就需要全局广播;如果你只需要应用内通信,那么你只需要应用内广播。

应用内广播(LocalBroadcast)使用的Handler的消息传输机制;应用间广播或者说是进程间广播(Broadcast)使用的则是Binder的机制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值