本文最后更新于:1 个月前
系统会在发生各种系统事件时自动发送广播,例如当系统进入和退出飞行模式时。系统广播会被发送给所有同意接收相关事件的应用。广播消息本身会被封装在一个 Intent
对象中,该对象的操作字符串会标识所发生的事件(例如 android.intent.action.AIRPLANE_MODE
)。该 Intent 可能还包含绑定到其 extra 字段中的附加信息。例如,飞行模式 intent 包含布尔值 extra 来指示是否已开启飞行模式。
接收广播
应用可以通过两种方式接收广播:清单声明的接收器和上下文注册的接收器。
清单声明的接收器
如果应用以 API 级别 26 或更高级别的平台版本为目标,则不能使用清单为隐式广播声明接收器。大多数情况下,可以使用调度作业来代替。
在应用清单中指定
<receiver>
元素。<receiver android:name=".MyBroadcastReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.INPUT_METHOD_CHANGED" /> </intent-filter> </receiver>
Intent 过滤器指定接收器所订阅的广播操作。
创建
BroadcastReceiver
子类并实现onReceive(Context, Intent)
。private const val TAG = "MyBroadcastReceiver" class MyBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { StringBuilder().apply { append("Action: ${intent.action}\n") append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n") toString().also { log -> Log.d(TAG, log) Toast.makeText(context, log, Toast.LENGTH_LONG).show() } } } }
如果应用当前未运行,系统可以启动应用并发送广播。
系统会创建新的 BroadcastReceiver
组件对象来处理它接收到的每个广播。此对象仅在 onReceive(Context, Intent)
期间有效。一旦从此方法返回代码,系统便会认为该组件不再活跃。
上下文注册的接收器
- 创建
BroadcastReceiver
的实例。 - 创建
IntentFilter
并调用registerReceiver(BroadcastReceiver, IntentFilter)
来注册接收器。 - 要停止广播,可以调用
unregisterReceiver(android.content.BroadcastReceiver)
。
注意注册和注销接收器的位置。如果使用 Activity Context 在 onCreate()
中注册接收器,则需要在 onDestory()
中注销,以防止接收器从 Activity Context 中泄露出去。如果在 onResume()
中注册接收器,应在 onPause()
中注销,以防止多次注册接收器(此举可以减少不必要的系统开销,在暂停时停止接收广播)。
对进程状态的影响
BroadcastReceiver
的状态会影响其所在进程的状态,因此不应从广播接收器启动长时间运行的后太线程。onReceive()
完成后,系统可以随时终止进程来回收内存,在此过程中,也会终止进程中运行的派生线程。要避免这种情况,可以调用 goAsync()
或使用 JobScheduler
从接收器调度 JobService
。
发送广播
sendOrderedBroadcast(Intent, String)
一次向一个接收器发送广播。当接收器逐个顺序执行时,接收器可以向下传递效果,也可以中止广播。sendBroadcast(Intent)
常规广播,会按随机的顺序向所有接收器发送广播。LocalBroadcastManager.sendBroadcast
将广播发送给与发送器位于统一应用中的接收器。
通过权限限制广播
带权限的发送
调用方法发送广播时,可以指定权限参数。接收器若要接受此广播,需要通过清单中的标记请求该权限。
带权限的接收
如果在注册广播接收器时制定了权限参数,广播方需要在清单中请求该权限。
安全注意事项和最佳做法
- 如果不需要向应用以外的组件发送广播,可以使用
LocalBroadcastManager
. - 如果有许多应用在清单中注册接收相同的广播,可能会导致系统启动大量应用,为避免此种情况的发生,可以优先使用上下文注册方法。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!