143 lines
4.2 KiB
Markdown
143 lines
4.2 KiB
Markdown
# Broadcast Receivers
|
||
|
||
It is the 4th component in Android
|
||
|
||
1. Activity
|
||
- User interface
|
||
2. Service
|
||
- Performs a long-running background task
|
||
3. Content Provider
|
||
- Storage and provision of data
|
||
4. Broadcast receivers
|
||
|
||
Components are *entry points*
|
||
|
||
###### Event-based
|
||
|
||
Respond to system-wide broadcast announcements
|
||
|
||
- The user has not necessarily done something, but the OS / phone / another application has
|
||
- e.g. the screen has turned off, battery is low, phone booted, new text
|
||
- Can be sent by an application, or received by an application from the OS
|
||
- Create the process, instantiate a `BroadcastReceiver`
|
||
|
||
**Intents** are sent to **specific activities**
|
||
|
||
- Explicitly or implicitly via intent filters
|
||
|
||
**Broadcasts** are sent to **anything** that cares to listen
|
||
|
||
- System-wide intent broadcasts
|
||
|
||
### Broadcasts
|
||
|
||
- Broadcasts are intents
|
||
- Send an intent to start an activity or service
|
||
- Send an intent to trigger broadcast receivers that subscribe to that particular class of intent
|
||
- Can define our own broadcast intents
|
||
- Cannot send system intents (battery, screen, etc.), as the security model prevents it
|
||
- Uses binder for messaging
|
||
|
||

|
||
|
||
#### Broadcast Receiver
|
||
|
||
- Must be registered
|
||
|
||
- Either in the manifest or context-registered
|
||
- **Context-registered** -> runtime
|
||
- To receive events while running
|
||
|
||
- Declare in manifest
|
||
|
||
```xml
|
||
<receiver android:name="MyReceiver">
|
||
<intent-filter>
|
||
<action android:name="com.example" />
|
||
</intent-filter>
|
||
</receiver>
|
||
```
|
||
|
||
- Specify broadcast intents we are interested in
|
||
|
||
- Receiver is registered at boot-time / install-time / run-time (context)
|
||
|
||
##### Implementation
|
||
|
||
- Sub-class `BroadcastReceiver`
|
||
- Specify which intents we are interested in
|
||
- Implement the `onReceive()` method
|
||
- Send a message to our application to change our behaviour
|
||
- Reduce the volume when a notification comes through
|
||
- Start an activity
|
||
- **Do not start activities** from broadcast receivers (jarring for user)
|
||
- Start a service
|
||
- A gateway to another component, e.g. start polling for emails
|
||
- Show a notification
|
||
- Alert the user that there is something that they need to interact with at *some point*
|
||
|
||
### Normal and Ordered Broadcasts
|
||
|
||
`sendBroadcast(intent)` - intent can be implicit or explicit
|
||
|
||
`sendOrderedBroadcast(intent, receiverPermission)`
|
||
|
||
`sendOrderedBroadcast(intent, receiverPermission, resultReceiver)`
|
||
|
||
Receive data back from the broadcast, `resultReceiver` will be treated as a final receiver at the end of the broadcast.
|
||
|
||
Ordered broadcasts are received by the highest-priority receivers first
|
||
|
||
Preferred receivers are given the chance to consume the broadcast before it is delivered to less preferred receivers
|
||
|
||
#### Sticky Broadcast
|
||
|
||
**Non-Sticky** - if you weren’t listening at the time, you’ve missed it
|
||
|
||
**Sticky** intents are cached by Android
|
||
|
||
- These are so much slower than just implementing direct calls within your own app IPC for each receiver to register. They will also incur a massive IPC overhead
|
||
|
||
Sticky broadcasts are **deprecated**
|
||
|
||
#### Local Broadcasts
|
||
|
||
Data broadcast will not leave the application
|
||
|
||
Other apps cannot send broadcasts to our application
|
||
|
||
- More efficient than sending a global broadcast
|
||
- No IPC
|
||
|
||
**Now deprecated** due to the MVVM architecture
|
||
|
||
#### Context-registered Receivers
|
||
|
||
Can no longer use a manifest-declared receiver for most implicit broadcasts
|
||
|
||
- Broadcasts that don’t target our app specifically
|
||
|
||
We can receive broadcasts as long as their registered context is valid
|
||
|
||
- If we register it in `onCreate`, we should *unregister* in `onDestroy` to prevent leaking the receiver
|
||
|
||
#### Broadcasts in practice
|
||
|
||
The application receiving the broadcasts must have been explicitly started / not explicitly stopped
|
||
|
||
- Applications cannot intercept broadcasts without the user having some awareness that they have given it permission
|
||
|
||
Either the sender or receiver of a broadcast can implement permissions
|
||
|
||
##### Lifecycle
|
||
|
||
Process is aggressively killed once `onReceive()` has returned
|
||
|
||
- Long-running code should be in a service instead
|
||
- `goAsync()`
|
||
- Can be called in `onReceive()` to keep the broadcast active after returning from that function
|
||
- ~10 seconds to do something
|
||
|
||
|
||
|