I read this article to understand the difference between implicit and explicit broadcast. After going through this I'm getting confused with the concept of broadcast itself.
In general, the term broadcast means to scatter/announce the information to a wider audience and whoever listens/receives the message can make use of it.
In the case of explicit broadcast when we know the component name (package name according to Java terms) and activity name (corresponding class name in Java terms) why shouldn't we invoke the Class.startActivity() directly instead of configuring it to the manifest - delivering it to aosp and gaining the control of method to be invoked. I feel the purpose of the term broadcast itself is not satisfied here since we know to whom we are going to send (1-1).
Why does AOSP introduced broadcast when we have the direct control of invoking a method in Java? Is this to bring structure to an application - something like this?
EDIT :
I should have asked it more specifically like why do we need a broadcast when we are under the same process.
I feel the purpose of the term broadcast itself is not satisfied here since we know to whom we are going to send (1-1).
The original general case of broadcast Intents (implicit broadcast) was a "true" broadcast, where an arbitrary number of apps can register to listen for the broadcast. The scenario where you specify a ComponentName or package name is a specialized subset of the broadcast IPC mechanism.
Why does AOSP introduced broadcast when we have the direct control of invoking a method in Java?
Broadcasts are one form of IPC for Android. "direct control of invoking a method" is not IPC, as you cannot invoke a method in another app. For communication within your own app, you do not need broadcasts. For communications between apps, you need IPC, and for that, broadcasts are one option.
Related
(The title is a bit weird because the words "code" and "app" are apparently forbidden in question titles.)
I have two Android apps, one is a normal unprivileged app and one is a system app with the permission to shut down the system. From my normal app I want to initiate the shutdown. I know the package name and I have full control over both apps. Both are signed with the same key.
What is the most concise way to run code in one app from another?
One way would be a Service that I can then start with intent.setComponent(...); startService(intent), but being a Service implies some background activity is going on, which isn't in my case.
Another way would be a BroadcastReceiver but that doesn't allow me to target a specific component, it requires an identifier whose purpose is conceptually to be received by other apps as well.
Is there another way with better fitting semantics?
but being a Service implies some background activity is going on, which isn't in my case.
Service using AIDL is simply an inter-process communication (IPC) mechanism. What the recipient of that communication does in response to that communication is up to it.
Besides, you have some background activity going on. You wrote:
From my normal app I want to initiate the shutdown
Shutting down a device is "background activity", at least in my interpretation of the expression.
Another way would be a BroadcastReceiver but that doesn't allow me to target a specific component
Sure it does. You can use setComponent() on a broadcast Intent the same way that you do for binding to a Service, or starting a Service, or starting an Activity.
There are downsides of using setComponent(), notably a dependency between the two code bases. Basically, the ComponentName becomes part of the API contract, and since that maps to a Java class name, you are limited in your ability to refactor that class (new name, new package). However, there's nothing stopping you from using setComponent().
For example, I describe using setComponent() for a broadcast in this blog post. In that case, I am deriving the ComponentName values via PackageManager, but that's just in service of this specific example.
Is there another way with better fitting semantics?
For a single interaction, "fire and forget" sort of thing, where you are not looking for any sort of acknowledgment, I'd send an explicit broadcast (i.e., a broadcast of an Intent that uses the ComponentName to identify the recipient). And I'd definitely use a signature-level permission to secure it.
While CommonsWare's answer is excellent and the explicit broadcast with a custom permission is usually the way to go, in this particular case I ran into an issue.
Apps cannot receive broadcasts until they have started an activity because until then they remain in "stopped" state. So an app with only a BroadcastReceiver won't work.
And since I need to have an activity anyway, I put the shutdown code in the activity.
I want to use android broadcast receiver in my application but I don't know exactly how to use the android broadcast receiver and how it is work in an android application.I found the many definition for this in Google but I didn't know exactly what did they mean.
With broadcast receivers you can either hook into system broadcast such as Intent.ACTION_BATTERY_LOW or you can create your own broadcasts. Why would you want to do this? Because broadcasts allow you to exchange information between your component and to have a loose coupling between them at the same time. A component which broadcasts a message does not need to know about the listeners and no registering of the listener is required. This allows you to implement the message passing pattern in your Android application.
You can create your own broadcasts either for interprocess communication, or you can use an optimized version for communicating inside the current process through the LocalBroadcastManager class.
The link given by Tim Castelijns will give you some examples.
Once you return from onReceive(), the BroadcastReceiver is no longer
active, and its hosting process is only as important as any other
application components that are running in it. This is especially
important because if that process was only hosting the
BroadcastReceiver (a common case for applications that the user has
never or not recently interacted with), then upon returning from
onReceive() the system will consider its process to be empty and
aggressively kill it so that resources are available for other more
important processes.
This means that for longer-running operations you will often use a
Service in conjunction with a BroadcastReceiver to keep the containing
process active for the entire time of your operation.
The above text has been taken from android site. But I am unable to find how to use a Service in conjunction with a BroadcastReceiver. Can someone please share some link for this or any example?
I found this link - stackoverflow. Is this the correct way of doing it?
The BroadcastReceiver is one way you can set up communication between your service and your application/activity. Basically the service can send a broadcast to your activity, then your activity will handle whatever it needs to inside the onReceive().
Inside your service you would send a broadcast using an intent with a specific intent action, in your activity you would register a receiver with the same action. This way when you send a broadcast your activity will be able to receive it.
A good example / place to start: (Look at section 7 for full code example)
http://www.vogella.com/articles/AndroidServices/article.html
Good Luck!
Are there any use cases in which I would want to use a BroadcastReceiver for something other than cross-application communication?
After reading the documentation, it seems like they are targeted at cross-application communication, but the idea of using them with the LocalBroadcastManager is also mentioned. I also read this post, which addresses the general usage of broadcast receivers. Neither seem to hit clearly on why it would be useful to use broadcasts and receivers for anything other than cross-application communication.
Does it have anything to do with their asynchronous nature, or maybe they're just used to move some processing out of the main activity?
Clarification: I guess the term cross-application was too general. I was considering the built-in actions such as
android.hardware.action.NEW_PICTURE
to be coming from applications. What I would like to know is: when is it useful to use a BroadcastReceiver for communication within my app - I guess this would narrow it down to custom intent actions/categories. Sorry if the way I'm asking this is confusing. I've only just recently begun programming with Android and I still don't understand the OS very well.
As it quotes in the post you linked: "A broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system."
Therefore, they are useful in "catching" system broadcasts, e.g., when the device has booted up, when the battery level changes, when your Wi-Fi has been turned on, etc.
Personally, I've used a BroadcastReceiver to start my app whenever the device receives a text message. In my case, this is preferred, as my app does not need to be running when the text message is received. Upon receipt, the system will broadcast an intent with an SMS_RECEIVED action. My BroadcastReceiver component, registered to accept this particular type ofbroadcast, will be notified and can then react as needed. In my case, it launches an Activity to notify the user of the text message and choose a particular reply text message.
This is just a specific example. There are many other broadcasts that the system transmits and your Receiver can get. Check this link and this post for more examples.
Clarification:
A LocalBroadcastManager is preferable in instances when you want rather simple way to communicate between app components without an intent being broadcast system-wide. Knowing this, you would want to go this route when the info you're passing is to be used only by your app. A LocalBroadcastManager is more efficient, generally simpler than using an IBinder interface, and can ensure that information isn't leaving your app.
For an example, suppose you have a Service that runs in the background to track and log some constantly changing data; let's say your battery level. The Service can run on its own without user interaction, saving the battery level to the disk as it changes. When you start your activity to view said data, it would use LocalBroadcastManager to register a receiver to accept the info the Service is sending, and update the Activity's UI in real time to reflect this. Since no other app needs the info from your Service, it's better to do this than broadcasting an intent to which any other app could have access.
To sum up, using a LocalBroadcastManager is:
More efficient.
More secure.
Simpler.
I started with a standard local android service, and used Binders with Listeners to communicate. Then: I began noticing some serious issues with handling orientation changes, so I decided to skip the whole binder thing, and just go with broadcasting intents (and using startService exclusively) that contain all the data/commands that need to be passed.
My question is: what are some of the pitfalls I have to look out for when using this approach?
Are there any disadvantages?
If you are supporting API Level 4 and above, use setPackage() to make your "broadcast" be a "narrowcast" -- keeping the broadcast within your app. By default, the broadcast is truly broadcast, to all apps, which may or may not be a good thing for your data.
Don't forget to unregister your BroadcastReceiver (i.e., don't register it and forget it). At the same time, you will need to consider what to do if the service wraps up and the activity is long gone (e.g., BACK button). One approach is to use an ordered broadcast with a low-priority manifest-registered receiver that will raise a Notification if no activity handles the broadcast -- this sample app demonstrates what I mean.
You might consider a Messenger instead of the broadcast approach, as it is intrinsically a "narrowcast", probably is a smidge less overhead, and can't be leaked. I am still working through the mechanics of using this with configuration changes, though.