I'm working on this project where I need Location updates plus data uploads even when the main Application is not in the foreground. I'm thinking of placing all location and networking functions in a Service (XService, for argument's sake) and communicate between the Activity (Main) and XService using broadcasts within the same process (no access for other apps).
I have not yet written the code, but the work flow goes something like:
1. Main -- Start. In onCreate, start a new Thread, and on it
instantiate and bind XService. 2. Main -- Login screen. Get data,
package it in an Intent and broadcast to XService. 3. XService --
Receive broadcast, unpack intent. Setup socket and data streams. Setup
LocationManager for updates. Broadcast to Main that the network is
ready. Upload data every time LocationManager updates.
4. Main -- Upon receiving the network-ready broadcast, prepare Intent for initialization and broadcast. 5. XService -- Receive
initialization-request broadcast, unpack, perform network task,
broadcast response. 6. Repeat ad nauseam as per user
interaction and any timed updates. x. Main -- On logout,
broadcast to XService. x+1. XService -- Send logout info to
server, close sockets, broadcast to Main that it is exiting
gracefully, then stopSelf(). x+2 Main -- Complete logout
procedure.
My main question is -- is this the right way of going about it?
Another question is: What happens when XService broadcasts a Location update to Main, but Main is stopped (i.e. not running in foreground)? I assume that since the BroadcastReceiver on Main is not instantiated due to Main being in a stopped state, the broadcast essentially does nothing. How does this unreceived broadcast impact (or not, as the case may be) XService or the process / device in general?
That makes sense. My suggestion is starting the service on the main thread, then forming your new thread within the Service class. This would package the Service nicely so that you don't have to spawn a thread to use it, you can just call it.
If Main is stopped and the Broadcast sends a message, it's a lost message. You want to avoid those by registering the receiver at OnStart and unregistering at OnStop. You can save any pertinent information that the Activity may need to know in the Service itself.
An alternative to the Broadcast Receiver is the Messenger class. (http://developer.android.com/reference/android/os/Messenger.html)
Related
What is difference between BroadcastReceiver and ResultReceiver in android?
Result Receiver:
Generic interface for receiving a callback result from someone.
Broadcast Receiver:
Base class for code that will receive intents sent by sendBroadcast().
EDIT:
Background: All networking operations/long running operations should take place away from the main thread. Two ways to do this :
Async task - For Simple networking like say retreive an image/ do db
processing
Service - For Complex long running background process
If you need to perform work outside your main thread, but only while the user is interacting with your application, then you should probably instead create a new thread and not a service. For example, if you want to play some music, but only while your activity is running, you might create an Async Thread. But if you want the process to continue even after the user exits the app (say a download) then use a service
Lets say you pick 2. Now
You activity sends a web request to your service
Your service executes that using say DefaultHttpClient
It sends back data to your activity.
The third step of receiving data here can be done in two ways
1.) Broadcast receiver: Multiple receivers can receive your data. Used if you want to send data/notifications across applications(say you are also interacting with fb and twitter, multiple receivers for your web broadcast),
whenever you send broadcast its sent system wide.
2.) Result receiver: Your application is the only receiver of the data. It is an Interface you implement and pass it to the intentService through putExtra. IntentService will then fetch this object
and call its receiver.send function to send anything (in bundle) to
calling activity. Result receiver has
preference over broadcast receivers if your all communication is
internal to your application
EDIT: I should also mention this caution
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise). This means that, if your
service is going to do any CPU intensive work or blocking operations
(such as MP3 playback or networking), you should create a new thread
within the service to do that work. By using a separate thread, you
will reduce the risk of Application Not Responding (ANR) errors and
the application's main thread can remain dedicated to user interaction
with your activities.
A BroadcastReceiver is a receiver receiving broadcasts. Those are sent by someone in the intention that there can be many receivers receiving them (like radio broadcasts).
A ResultReceiver on the other hand is intended to receive a callback result from someone. So this could be compared with a walkie talkie, where you call someone and then are going to receive an answer (a result) from the one you called.
These two classes are completely different. It's actually quite the same difference as between Broadcast and Result.
what it Broadcast? In simple words it's some message which is visible to whole system and it can be consumed by every part of the system (which knows the contract), it wasn't originated by smb reuest;
what is Result? It's something we're expecting to receive from another part of the system. Usually there's only one receiver for result and usually that receiver has requested processing to obtain result (feel the difference - for broadcast nobody needs to do any 'request' to let it originated);
That was explanation from logic point of view. From the code perspective if You would compare BroadcastReceiver and ResultReceiver You could observe huge difference. Basically both classes are built on top of IPC but BroadcastReceiver is much more complex because of it's different nature (which I've tried to explain in first part).
Broadcast Receiver
A broadcast receiver is a component that responds to system-wide broadcast announcements. example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event.
Result Receiver
If your service is going to be part of you application then you are making it way more complex than it needs to be. Since you have a simple use case of getting some data from a Restful Web Service, you should look into ResultReceiver and IntentService.
This Service + ResultReceiver pattern works by starting or binding to the service with startService() when you want to do some action. You can specify the operation to perform and pass in your ResultReceiver (the activity) through the extras in the Intent.
I have been going through this very short tutorialand I am confused as to what is the function of the service. I am also confused as to what is the function of the broadcast receiver.
I tried to do some research and here is what i understand:
- services run in the background, but... i don't understand why we need something
to run in the background to make the phone wake up at a certain time.
I "think" the broadcast receiver acts as some kind of catcher's mit, in that
when the pending intent is launched at a specific time, it catches it then
launches the service... how close am I to the truth ?
As i think that services are used for long running tasks and especially in those cases that run when your main activity is not running.
For this functionality we can use threads this make us to say that a thread is created inside our activity and it can't be active outside of the our main activity,
that is the drawback that's why we have services .
Document URL
Services can be used to run long running tasks independent of your screen flow. For example, consider your application require to communicate with a server via socket throughout its running duration, you can start a service to handle this. Imagine that against starting the socket and making connection at the start of every activity, and clean up when that activity stops.
Services by default run in the main thread. But you can start separate threads in a service context, just like you do in an Activity. If your background task can overlap across multiple activities, then it is better to start it in a Service context because every Thread/AsyncTask created retains the context that it is running. In that case your Activity will be retained even if user navigates to another activity because a thread started from that Activity is already running. If Activity is retained, it might prevent all its views, images getting garbage collected.
What Services can't do is to directly alter UI components. For that it needs to communicate with the currently running Activity context. In short, if your non UI task does overlap the life time of a particular Activity, it is better to shift that task to a Service.
What is the function of the service ?
A service is a component which runs in the background without direct interaction with the user.
As the service has no user interface, it is not bound to the lifecycle of an activity.
Services are used for repetitive and potentially long running operations, i.e., Internet downloads, checking for new data, data processing, updating content providers and the like.
TO READ: Service
What is the function of the broadcast receiver ?
Broadcast receivers are the second kind of component. Like services, they only exist in the background and don't interact with you directly. But unlike services, they can't stay running or perform long tasks: they exist to respond to events. And unlike activities and services, more than one broadcast receiver can be started in one go.
Each broadcast receiver can react straight away, for example by creating a notification, or it can start a service or an activity to take further action. As soon as the broadcast receiver has handled the event, it is stopped and will not run again until another similar event is broadcast.
TO READ: BroadcastReceiver
I don't understand why we need something to run in the background to
make the phone wake up at a certain time ?
We don't want that the application should necessarily be in the foreground to wake the phone up.
Moreover we want notifications in the background.
We started the service. Now even if we close the application, you can get the phone wake up notification. This is so useful.
Services are great to interact with a user through notifications (a way of alerting a user about an event that he needs to be informed about or even take some action on getting that information). Many a time, applications will need to run processes for a long time without any intervention from the user, or very rare interventions. These background processes need to keep running even when the phone is being used for other activities / tasks.
To accommodate for such a requirement, android has introduced the "Service" component.
It runs in the background until it stops itself. This means that a service could be keeping your phone awake (using a wake lock), running down the battery, or using lots of network data, without anything showing on the screen.
I "think" the broadcast receiver acts as some kind of catcher's mit,
in that when the pending intent is launched at a specific time, it
catches it then launches the service... how close am I to the truth ?
Correct, they are meant to respond to an intent (usually one sent by a service or a system event), do something, and be done. When an intent is broadcast via sendBroadcast, it will be sent to all receivers that have matching intent filters.
Service - is a component of android, which runs in the background with out any UI. By default service will run in Main thread only.
Thread - is not android component, but still one can use thread to do some background task. Using thread in place of service is discouraged
The Situation:
Note: This is a followup of a previous question that takes care of how to setup the handler/message communication between activity/service. See: link
Activity connects to a started Service using binding. Activity gets a local binder with a reference to a service Handler back. Activity and Service exchange Message objects through eachothers Handlers. When user is done with App, user signals Service to quit the started Service (shutdown the service). Within the service (=mainThread) another thread is running, the serviceThread. The serviceThread is capable of running more subthreads, fully controlled by the serviceThread. Communication is handled between activity and the serviceThread, not through the mainThread of the service!!!
The Problem:
How do I gracefully shutdown the Service when inside the Service several threads are running endlessly (until I signal a message saying: "pack your backs, go home!", aka: EXIT_SERVICE.
Solution candidates:
Scenario 1: from the activity side, send a EXIT_SERVICE message to the serviceThread that is running within the service (not the mainThread!). When all subthreads of serviceThread have been cleanup/stopped send a message back to the activity indicating that it is now safe to call the stopService(Intent) method which actually stops the service. The activity can now call finish() and the App is exited gracefully.
Scenario 2: from the activity side, send a EXIT_SERVICE message to the serviceThread which will cleanup all subthreads. After that is done the serviceThread sends a message to the activity that the service is to be shutted down completely and after that message is sent, sends a message to the mainThread handler of the service to actually shutdown the service. The service receives the shutdown-message and cleans up varialbles and calls stopSelf(int).
The service is stopped and the activity knows that it can stop too, WITHOUT calling stopService(Intent)! The App is exited gracefully.
Scenario 3: from the activity side, call the stopService(Intent) method, which will deliver the Intent to the service to stop the service. In the service this Intent is intercepted (I don't know if this is possible and how to do that yet... but assuming this can be done) before the actual service code that stops the service is executed. Before the service actually stops, other code is executed first which cleans up the threads by sending a EXIT_SERVICE message to the serviceThread. After the serviceThread has cleaned up, it sends a message back to the mainThread (the service itself) and the code continues to execute the normal code that was normally executed when the Intent to stop the service wasn't intercepted. The App is exited gracefully.
So, I have three options on how to gracefully stop the Service. The problem is which scenario is the "best" (less error prone, quickest in shutting down, easiest to implement). For example: what happens when the activity is destroyed because the user switched portrait/landscape mode right at the moment the "stop service" message or Intent was sent?
I think scenario 3 is a nice solution, because it doesn't need a lot of extra coding on the activiy side, only stopService(Intent) and finish(). The service can also be in the process of stopping while the GUI is already gone. Only thing is how to intercept the stop Intent and act upon that signal.
Please share your thoughts....
What is difference between BroadcastReceiver and ResultReceiver in android?
Result Receiver:
Generic interface for receiving a callback result from someone.
Broadcast Receiver:
Base class for code that will receive intents sent by sendBroadcast().
EDIT:
Background: All networking operations/long running operations should take place away from the main thread. Two ways to do this :
Async task - For Simple networking like say retreive an image/ do db
processing
Service - For Complex long running background process
If you need to perform work outside your main thread, but only while the user is interacting with your application, then you should probably instead create a new thread and not a service. For example, if you want to play some music, but only while your activity is running, you might create an Async Thread. But if you want the process to continue even after the user exits the app (say a download) then use a service
Lets say you pick 2. Now
You activity sends a web request to your service
Your service executes that using say DefaultHttpClient
It sends back data to your activity.
The third step of receiving data here can be done in two ways
1.) Broadcast receiver: Multiple receivers can receive your data. Used if you want to send data/notifications across applications(say you are also interacting with fb and twitter, multiple receivers for your web broadcast),
whenever you send broadcast its sent system wide.
2.) Result receiver: Your application is the only receiver of the data. It is an Interface you implement and pass it to the intentService through putExtra. IntentService will then fetch this object
and call its receiver.send function to send anything (in bundle) to
calling activity. Result receiver has
preference over broadcast receivers if your all communication is
internal to your application
EDIT: I should also mention this caution
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise). This means that, if your
service is going to do any CPU intensive work or blocking operations
(such as MP3 playback or networking), you should create a new thread
within the service to do that work. By using a separate thread, you
will reduce the risk of Application Not Responding (ANR) errors and
the application's main thread can remain dedicated to user interaction
with your activities.
A BroadcastReceiver is a receiver receiving broadcasts. Those are sent by someone in the intention that there can be many receivers receiving them (like radio broadcasts).
A ResultReceiver on the other hand is intended to receive a callback result from someone. So this could be compared with a walkie talkie, where you call someone and then are going to receive an answer (a result) from the one you called.
These two classes are completely different. It's actually quite the same difference as between Broadcast and Result.
what it Broadcast? In simple words it's some message which is visible to whole system and it can be consumed by every part of the system (which knows the contract), it wasn't originated by smb reuest;
what is Result? It's something we're expecting to receive from another part of the system. Usually there's only one receiver for result and usually that receiver has requested processing to obtain result (feel the difference - for broadcast nobody needs to do any 'request' to let it originated);
That was explanation from logic point of view. From the code perspective if You would compare BroadcastReceiver and ResultReceiver You could observe huge difference. Basically both classes are built on top of IPC but BroadcastReceiver is much more complex because of it's different nature (which I've tried to explain in first part).
Broadcast Receiver
A broadcast receiver is a component that responds to system-wide broadcast announcements. example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event.
Result Receiver
If your service is going to be part of you application then you are making it way more complex than it needs to be. Since you have a simple use case of getting some data from a Restful Web Service, you should look into ResultReceiver and IntentService.
This Service + ResultReceiver pattern works by starting or binding to the service with startService() when you want to do some action. You can specify the operation to perform and pass in your ResultReceiver (the activity) through the extras in the Intent.
We have a network client application, and we are trying to validate our approach to processing responses from the server in conjunction with device rotation. essentially, we do this,
activity registers a receiver for network responses
activity initiates a network operation by starting an intent service
service responds by broadcasting an intent it's finished
our (perceived) problem is that when the device is rotated, the activity is destroyed / recreated. during the time between when the activity's receiver is unregistered in onPause() and when it's re-registered in onResume(), we may have missed the intent that is broadcast by the service.
is this a real problem?
if so, we have hypothesized the following solution,
first, don't use intents to communicate between activity and service
create two blocking queues: network requests and responses in say the application class
service starts a thread that take()'s from the request queue
activity starts a thread that take()'s from the response queue
activity offer()'s to the request queue when it wants to start a network operation
service offer()'s to the response queue when post the result of a network operation
Yes this can happen in rare circumstances but it will happens for sure if the user receives a call. Again your activity will be paused and then resumed, If the user talks for a long time your activity will loose a bunch of broadcasts from the service.
My advice is that you must not use broadcasts to do two way communications between application's in situations that a response from a component such as a service, requires immediate attention. What mechanism you will use is depending from the situation. In my latest project I am using a service in order to update an app-widget, in this scenario I am using static code in the service in order to do some queries or to request some actions.
Your thinking sounds good but it may hides a complex implementation, If I was in your position I would consider to use the built in service mechanism called Bound Services. I have not used it so far but it seems that it is covering your needs.
EDIT
So based on the bound services concept I propose the following flow:
Activity starts, a so called, sticky service.
Service registers the receiver for network responces.
Service maintains an Ibinder object with the needed information based on the network responces.
Activity bounds to the service whenever it wants and retrieve the Ibinder object with the info and does the required actions.
When it's time to end the application, Activity stops the service and finishes itself.
Hope this helps...