Android的BroadcasrReceiver机制

本文深入探讨了Android应用中广播注册的两种主要方式:动态注册和静态注册。动态注册灵活可注销,有助于降低系统开销;静态注册则提供持久功能,如定时任务或服务通知。文章特别强调了在onResume()中注册广播时应在onPause()中注销,并解释了静态注册不需注销的原因,以避免不必要的内存占用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们都知道,Android的广播注册有两种方式,分别为静态和动态注册,动态注册具有灵活性,可随用户需要注销,更大的遵循用户的意愿,在API文档中,提到:

Note:    If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause(). (You won't receive intents when paused, and this will cut down on unnecessary system overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back in the history stack.

即声明了动态注册的一个该注意的地方,假设广播接收器在onResume()中注册,则应该在onPause()中注销,且不要在Activity.onSaveInstanceState()中注销广播,后面这句才是重点,因为这个方法在用户从历史任务(最近打开)中启动应用时不会被调用,这个note应该时常记住,避免不必要的bug出现;


而静态注册则能获得持久性的功能,例如天气预报的默认更新功能、例如现在市面上一部分启动器(Launcher)用于重绘icon等等,静态注册能帮我们做到一些有趣的事情,但是一个广播一直保持在激活状态,到底是好事还是坏事?经过n次的接收、处理广播之后,是否会变得占内存、消耗资源?

The receiver tag declares an BroadcastReceiver class that is available as part of the package's application components, allowing the application to receive actions or data broadcast by other applications even if it is not currently running.

Zero or more intent-filter tags can be included inside of a receiver, to specify the Intents it will receive. If none are specified, the receiver will only be run when an Intent is broadcast that is directed at its specific class name. The receiver tag appears as a child tag of the application tag.

首先,静态注册需要一个单独的类来继承BroadcastReceiver,这个类作为app的包中的一部分,并且可以接收到action。第二段话中则提及,如果没有定义intent-filter,则只当广播被指向发送到Receriver类名的时候(有几个方法可以指定发送到某BroadcastReceiver,此处不提),这个广播接收器才会启动,也就是说,静态注册的广播接收器,即使不注销,也是不会很耗资源的。然后查看onReceive()方法,能看到:

public abstract void onReceive (Context context, Intent intent)
Added in  API level 1

This method is called when the BroadcastReceiver is receiving an Intent broadcast. During this time you can use the other methods on BroadcastReceiver to view/modify the current result values. This method is always called within the main thread of its process, unless you explicitly asked for it to be scheduled on a different thread usingregisterReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler). When it runs on the main thread you should never perform long-running operations in it (there is a timeout of 10 seconds that the system allows before considering the receiver to be blocked and a candidate to be killed). You cannot launch a popup dialog in your implementation of onReceive().

If this BroadcastReceiver was launched through a <receiver> tag, then the object is no longer alive after returning from this function. This means you should not perform any operations that return a result to you asynchronously -- in particular, for interacting with services, you should use startService(Intent) instead of bindService(Intent, ServiceConnection, int). If you wish to interact with a service that is already running, you can use peekService(Context, Intent).

The Intent filters used in registerReceiver(BroadcastReceiver, IntentFilter) and in application manifests are not guaranteed to be exclusive. They are hints to the operating system about how to find suitable recipients. It is possible for senders to force delivery to specific recipients, bypassing filter resolution. For this reason, onReceive() implementations should respond only to known actions, ignoring any unexpected Intents that they may receive.

Parameters
context The Context in which the receiver is running.
intent The Intent being received.
其中加粗体字的那段话要特别注意,意思是如果一个广播接收器是通过静态注册的,那么当onReceive方法执行完毕之后它并不会存活太久,也就是意味着我们不需要对此接收器进行任何让它返回结果的操作——特别是异步的情况下。所以对于静态注册的广播接收器,我们不必担心它的注销问题,它并不影响设备的运行。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值