Hello everyone, good morning, another very nice day, let’s fight and move forward together.
This is the third in our interview series. In this installment, we’ll take a look at one of Android’s four major components: BroadcastReceiver.
Android: How to understand the lifecycle of an Activity
preface
As one of the four components of Android, BroadcastReceiver has many application scenarios. So I don’t think any engineer with any level of Android development experience is going to stumble on this. But, uh, there are some details that maybe we can take note of.
In fact, I encountered this question in the interview process. Now please allow me to use “Brother Liu Xue” ideas to lead you into the interview camp.
What is the underlying principle of BroadcastReceiver?
Android BroadcastReceiver is a global listener that listens to/receives broadcast messages sent by applications and responds to them. It adopts the observer pattern in the design pattern, which decouples broadcast based on message subscribers, message publishers and message centers (AMS: Activity Manager Service) to form subscription relationships through Binder mechanisms.
There are two ways to register a BroadcastReceiver
The two ways to sign up for Android Broadcast are certainly not difficult for anyone, in fact I suspect only a small number of Android development candidates will encounter this question, there is nothing special here, the familiar can be skipped.
-
Static registration Static registration broadcast only needs to be declared in the androidmanifest.xml tag. Some attribute descriptions are attached below.
< receiver android: enabled = [" true "|" false "] / / the broadcastReceiver will receive radio from the other App / / the default value is presence of intent - filter in the receiver Decision: If intent-filter is present, the default value is true, Otherwise to false android: exported = [" true "|" false "] the android: icon = "drawable resource" android: label = "string resource" / / inheritance Android :name=".mbroadcastReceiver "// BroadcastReceiver can receive broadcasts sent by BroadcastReceiver only if the BroadcastReceiver has the corresponding rights. Android: Permission ="string" // BroadcastReceiver specifies the process in which it runs. Each of the four basic components of Android can specify its own independent process Android :process="string" > // Used to specify the type of broadcast this broadcast receiver will receive // In this example, used to receive the broadcast when the network state changes <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>
Copy the code -
Dynamic registration Dynamic registration is registered by calling registerReceiver() under the Context. You can call unregisterReceiver() to unregister. Note that active broadcasting is best registered in the Activity’s onResume() and unregistered in onPause().
Why is it recommended that dynamic broadcasts be unlogged as far as possible in onPause()?
We can start by looking at the Activity lifecycle.
The first registration must be deregistration, otherwise it is bound to cause memory leaks. Notice the red box on the way up. An Activity may be destroyed after executing onPause() when the system is running out of memory and needs to reclaim resources it occupies. OnPause () and onDestroy() do not execute at all, and onPause() is a good way to avoid memory leaks due to the nature of the calls that must be made.
The difference between the two registration methods can also be seen in the diagram.
Let’s talk about common broadcast types on Android
The most common way in the Android field is to directly call the methods provided by Context sendBroadcast() and sendOrderBroadcase() to send unordered broadcast and ordered broadcast.
Unordered broadcast Unordered broadcast is completely asynchronous and is sent through context.sendbroadcast (), which is relatively efficient. As its name suggests, unordered broadcast is unordered for all broadcast receivers. In other words, all receivers cannot determine the order in which they receive the message, and as a result, an out-of-order broadcast cannot be stopped. When it is sent, it notifies all receivers of the broadcast until there are no matching receivers.
Orderly broadcast orderly broadcast through the Context. SendOrderedBroadcast () method to send. The biggest difference between an ordered broadcast and an unordered broadcast is that it allows the receiver to set priorities, and the broadcast will follow the priorities set by the receiver. A higher-priority receiver can process the broadcast or stop further transmission of the broadcast. The broadcast is sent first to a Receiver with a higher priority (Android: Priority), and this Receiver has the right to decide whether to continue the broadcast to the next Receiver or terminate the broadcast directly.
Are there other types besides disordered and ordered broadcasting?
There may still be quite a few friends who know Sticky broadcasting.
-
StickySticky Radio, as its name suggests, is a sticky radio. Once it’s sent, it stays in the system until a matching recipient is sent. It USES Context. SendStickyBroadcast () method to send radio. If you want to send a Sticky broadcast, you need to have BROADCAST_STICKY, which can be registered in androidmanifest.xml. A SecurityException is thrown. As far as the system is concerned, only the last Sticky broadcast will be kept, and it will be kept forever, that is, if the Sticky broadcast we send is not cancelled, it will be received when there is one receiver, and the next one will still be received. So we need to call the removeStickyBoradcast() method to cancel it when appropriate. As you can see from the official documentation, StickyBroadcast is marked as @deprecated. For security reasons, it has been marked as Deprecated and is no longer recommended. We, as developers, need to be cautious about using methods labeled @depracated.
Sometimes for data security reasons, we want to send a broadcast only ourselves (this process) can receive, how to handle?
First, broadcasts in Android can communicate across processes because exported is true for intent-filters. So it’s hard for us to have this demand:
-
For certain sensitive broadcasts, we don’t want to expose them to the outside world.
-
Another App may send a broadcast that matches the current App intent-filter, causing the App to continuously receive and process the broadcast.
This is really bad news, we have to make our applications efficient and secure enough.
It is natural to set the exported value to false when registering a broadcast and add permissions to the broadcast of your App. However, the problem is that the unauthorized value is a string, which is not safe in the face of such powerful decomcompiling technology.
To solve this problem, it is not difficult to think of sending messages to the main thread’s Message Queue so that only the main thread’s Handler can distribute and process them. Or specify the broadcast receiver’s packageName with intent.setpackage (packageName) when sending a broadcast.
I didn’t know there was a LocalBroadcastManager class in the Support V4 package until we included the BroadcastUtil utility.
Local broadcasting has joined our family with Android Support v4:21. It is managed using the LocalBroadcastManager (hereinafter referred to as LBM) class.
Using LocalBroadcast is very easy. You only need to replace the CORRESPONDING API of Broadcast with the API provided by LBM.
LBM is a singleton object, you can use LocalBroadcastManager. GetInstance (Context Context) method to get to. Broadcast related methods defined in Context have corresponding apis in LBM. Interestingly, LBM uses sendBroadcast() and sendBroadcastSync() to distinguish asynchronous from synchronous.
Update UI with radio on Android?
After all this nonsense, we finally get to the question of the title.
Direct answer: Yes, why not? Don’t we use this a lot in real development?
Well, you’re a real Android developer, but before certifying you as “qualified,” ask about the life cycle of BroadcastReceiver.
What? The life cycle of a BroadcastReceiver? (Source: BroadcastReceiver) (source: BroadcastReceiver) (Source: BroadcastReceiver) (Source: BroadcastReceiver)
So, you faltered.
There are a lot of people who understand the life cycle of BroadcastReceiver. Broadcastreceivers have a life cycle, but they are short and very short. When its onReceive() method completes, its life cycle ends. Since the BroadcastReceiver is no longer active, it is highly likely that the system will kill it. This means that if you open the thread in onReceive() to perform an asynchronous operation or to open a Dialog, the process may be killed by the system without reaching the desired result.
So, the correct answer is?
Updating the UI is too broad a definition. In fact, it is possible to use BroadcastReceiver to update the UI in most cases, which has caused many people to say yes.
In fact, we know that the Receiver also runs on the main thread and cannot do time-consuming operations. Although the timeout is higher than the Activity’s 5 seconds, it is a full 10 seconds. This does not mean that all of our actual development of the updated UI operation time is within the safe range.
Also, this is not recommended for frequent UI updates. Android broadcasts are both sent and received at a cost. Binder interprocess communication is used for transmission, so the system must be prepared for interprocess communication. There may also be other factors that cause broadcasts to be sent and arrived on time (or delayed reception).
Is that possible?
Probably, and very easily. Note that The Android ActivityManagerService has a special message queue to receive outgoing broadcasts. SendBroadcast () returns immediately after execution, but incoming broadcasts are only queued and not necessarily processed immediately. When the current broadcast is processed, it is distributed to the registered broadcast ReceiverDispatcher, The ReceiverDispatcher then passes the broadcast to the Message Queue of the thread that receives the Receiver (the familiar Message Queue of UI threads).
The whole process involves two Binder interprocess communications from ActivityManagerService to ReceiverDispatcher, and finally to the UI message queue. If processing a message in the base blocks the UI, It also delays the execution of your onReceive().
What’s the difference between BroadcastReceiver and EventBus?
EventBus, a popular library on GitHub, currently has a 16.3K star, which is strong enough.
So of course this question comes up in many interviews. This is not, I was asked this question by the interviewer in the interview, and I was hit in the face. At that time, I felt like being shocked, and the answer was not good.
As you know, broadcast is one of the four components of Android. System System-level events are notified through broadcast, such as network changes, power changes, and SMS receiving and sending status. So, for Android notifications, we have to broadcast locally.
But!! Broadcasting, compared to other implementations, is very heavyweight and consumes more resources. The advantage of onReceive() is its close connection to the SDK. The onReceive() method comes with Context and Intent parameters, so it is somewhat convenient. However, if the Context and Intent are applied with little or no interaction, Using radio is really a waste!!
The EventBus?
First, the advantages:
-
When it comes to the advantages of flexible scheduling, this must be the first thing that comes to my mind. Because it’s so flexible, in real development it feels like it can go where it wants, and doesn’t need to focus on Context injection and passing like a broadcast. The parent class can also directly inherit the monitoring and processing of the notice to the subclass. The priority can be set for Subscriber to pay attention to the notice with a higher priority, and its sticky events can ensure that the notice will not be ignored due to Subscriber’s absence. Inheritability, priority, and stickiness are the biggest advantages of EventBus over broadcast, observer, and the like, which make it possible to create well-structured, tightly organized notification systems.
-
Go to EventBus’s website and take a look at readme. md. You can’t make it any easier. Add a dependency to build. Gradle. If you don’t want to create an instance of EventBus, you can simply call the static method eventbus.getDefault ().
-
Fast and lightweight As a GitHub star project, performance is assured.
If EventBus is so great, let’s use EventBus to set up communications.
No one is perfect, nothing is perfect. EventBus also has its Achilles heel. The biggest drawback of EventBus is its logic. If you look at the code, you can’t read it. Another problem is that the observer-specific interface bloat disadvantage comes with your project as your program gets bigger. Can you imagine how many Event postclasses feel?
In general, because EventBus is geared toward unified processes, try It out in complex situations where interface callbacks alone can’t handle component communication.
Having said all that, do you still have to choose between broadcasting and EventBus?
Welcome to follow nanchen’s official account: Nanchen if you like, you can choose to share with everyone. If you have a good article, welcome to contribute, praise all belong to you.
Long press the qr code above to pay attention
Do not finish the open source, write not finish hypocritical
Let’s take a look at Nanchen’s growth notes