I have an application that needs updating constantly. I would like to create a job (Service, thread ...?) that execute the polling over all the activities. I need to update some data even if i'm not on the activity that needs to.
I would not create a service because actually I don't need to update tha application along it is closed.
What do you suggest?
Thanks
a.
I think you are confusing an Activity with the data that it presents to the user. You do not mess with other activities that are not currently on screen.
If I understand correctly, you want to update some data that is shared among your activities whenever any activity is currently visible.
You could create a Service which in turn uses a separate thread to do its polling. Then in each of your activities that you want the polling to be run you call startService in the onResume method of the activity and stopService in the onPause method of the activity.
Also make sure you use returnSTART_STICKY at the end of your service's onStartCommand method.
Related
Let's say we have an Android app that consists of a MainActivity, and also a bound intent service (or any other background service that continues to run while MainActivity is paused).
Lets say we have some variables belonging to MainActivity, MainAcitivity.variable1, and MainActivity.variable2.
Is it safe/normal to update these variables from the background service while MainActivity is paused? I know that it works without errors, but it seems strange to me that it is possible to interact with a class/thread that is "asleep." If you send multiple updates while Main is paused, do they all end up in a buffer that gets dealt with when Main is resumed? or do the updates happen immediately?
What technical subject to these questions have to do with?
Thankyou!!
You shouldn't get used to this. simply because your Service will not be able to see your Activity's variable when the app is closed.
A very good solution is to cache the changes made by the Service in local storage, and use BroadcastReciever to update the Activity if it is running. In addition to that, the Activity should get data from the storage in the onResume() method and update the UI accordingly.
So basically what i am trying to do is i want a service that runs in background and updates the LatLong to the server. This operation needs to happen all the time even if the application is running or not.
Now when the application is launched i want the service to calculate the distance between the latlong and update the UI in addition to the work that it was already doing i.e. updating the latlong to the server. i want the service to do the additional work for multiple activities. lets say i launch the application and i am on Activity A, onclick of a button on Activity A the service starts updating the UI and when we click gain it stops updating. Now i am on Activity B and on click i want the service to do some work in addition to the updation of LatLong and update the UI.
What would be the best approach to achieve this.??
EDIT
The problem i am facing is not getting the service update the UI but making the activity communicate with the service when it has already started.
i can pass on some data when i am starting the service but how to communicate with the service when it has already started. How to tell the service that see you are already running and doing some operations now you have to perform some more operation on top of the previous operation.
I can make some static method in the service and call them when i need to perform the extra operation but i dont wanna do that.. i want to better approach.
Here is the basically services runs on the same main thread process as ui. When you want make it run continuously you have run it in your tread. In this way you avoid service being get stopped as application go in background or killed. (Please take look at Service.START_STICKY flag, this is what you need as i guess).
And more coming your second problem of activity getting updated with service information or data that is being collected for this you need look at " How Bind the service". (In activity check for service connection and Binding to a activity, Unbindibg is also there have look at it also). Activity has all the call backs for it you need to implement binder.
EDIT
Service to update ui has to have send and receive intent mechanism. You can broadcast and intent from the services check your activity is running or not. If running broadcast intent and have receiver in activity to listen it.
You can do it by interface mechanism too
I have a application in which I have a UART (Serial Comms) to service and several other "tasks" that require separate worker threads to keep the UI responsive. My problem is in understanding when/where I should create these threads and when they get terminated. Currently, I am creating them in the OnCreate() of the main UI Activity. But, this is causing havok, as I recently needed to "jump" from one Activity back to the Main activity. The recommendation was to use an Intent and StartActivity() with the appropriate flags to "clear to top". But, this of course causes a whole new set of instances for my threads, and everything unravels. Should I be using a Service, tied to my UI somehow? I have subclassed my Main Application, so I have the OnCreate() of my Application. I'm leaning towards that, but can't seem to grasp the life cycle of the Application versus the Activities.
Use a service. You have an ongoing task that isn't inherently attached to one particular activity.
You can start a long running task with startService and the service will not be killed until it's finished. Meanwhile, Context#bindService will keep the service alive as long as anything is bound to it.
General rule of android concurrent programming
If you need to do something off the UI thread and return a result, use an AsyncTask created when you want to use it
If you have a 1 off requirement to do some work (say post a webservice request), use an AsyncTask
If you repeatedly want to do something inside a single activity but you don't need to run after the activity is destroyed or send data to another service, use a thread
If you need to talk to multiple activities, use a service.
If you need to run before/after your launching activity ends, use a service
I'm developing an app with a service that forwards calls to a web-service, and a few activities that place those calls. The activities need to process the results of those calls. For example, I have a writeComment method on the service, that accesses the web-service and returns some information about the newly written comment.
Right now I let the Activity take care of all the threading. The Activity binds the service, and then uses an AsyncTask that calls the bound service's writeComment method.
All works well as long as the Activity isn't stopped while the AsyncTask is running. If it does (easily happens when flipping the phone), the AsyncTask dies a violent death when trying to update the UI in onPostExecute. I'm not entirely sure how to fix this - I do need to let the user know the server has been updated.
If I go the other way around, and register a callback with the Service, I'm still a bit stump, because I need to notify the Service the Activity has changed - I need to tell it not to notify me in the first Activity's onDestory, and reregister in the second Activity's onCreate. And I need to handle the case where the asynchronous task completes after onDestroy and before onCreate.
What is considered Best Practice in this case?
Thanks,
Itay.
My intuition tells me to let the service handle the threading. Services are far less transient (although still transient to some degree) than activities and therefore you'll have less issues of threads trying to interact with a Context (be it an Activity or a Service) that's no longer there. Have you looked at the IntentService class? It handles a lot of the threading for you.
In my app, I have a long-running service and Activities that need to render data in the service. The service also pings the Activities when there is a change but the Activity can also query the service. The way I approached this was two-fold.
Firstly, I bind my activity to the Service in order to send messages from Activity to service.
Secondly, the Service sends notifications with Broadcasts and the Activity listens for those broadcasts. I set that up in the Activity onResume and tear it down in the onPause. I think this is the part that you're missing.
I got some concerns about AsyncTask that I could not clarify when reading the documentation.
My app main Activity runs several AsyncTask's when it's created. These AsyncTask's mostly download data or retrieve data from the DB.
If I go to a different Activity, will the AsyncTask's created on
this one continue executing? Or will they stop working and leave the
task half done? If so, will they go on somehow when getting back to
this activity?
In order to start one of the activities from the
one that is running the AsyncTask's, I need one of the AsyncTask's
to be fully executed. How do I set this constraint? Could you show
me some sample code of this, please?
Thanks
If I go to a different Activity, will the AsyncTask's created on this one continue executing? Or will they stop working and leave the task half done? If so, will they go on somehow when getting back to this activity?
Yes, it will continue to run. This can be a bit of a double-edged sword as it will typically also hold on to the Activity instance, causing it to live beyond its onDestroy() callback, which is not ideal. If the task you are running does not have the same lifecycle needs as the Activity itself, it may be better placed into a Service.
In order to start one of the activities from the one that is running the AsyncTask's, I need one of the AsyncTask's to be fully executed. How do I set this constraint? Could you show me some sample code of this, please?
There are way too many ways to do this, many depending on the architecture of your application, to provide specific sample code...but here are a few higher level ideas. Since AsyncTask provides a simple callback method on the main thread (onPostExecute) when the task execution is complete, you can set a flag at that point. Or perhaps simply check for the existence of whatever data the AsyncTask is retrieving from any code where the Activity would be launched. Again, a Service would provide good context for this, as multiple Activities could connect to the service and check the task status before moving forward.
Another option, depending on your application, is to have the result of the task dumped into a ContentProvider. ContentProviders include a nice interface for notifying observers of changes without resorting to global Broadcast Intents.
HTH
Ive done something similar to this before using Intents and Broadcast Receivers.
If you get the Async tasks to send a global or app-wide intent when they are finished, its easy enough to have a receiver pick it up if you construct them properly. By having a receiver created when you push a new activity onto the stack, and have the receiver close when an activity is paused, there will always be a receiver out there to grab the intent and be told that the (example: data is downloaded from the db) and act on that.
If you try and start an activity that requires that data, you can either deny the creation of that activity if the intent hasn't been found yet, or create the activity and have it put up a progress bar or something while the data finishes downloading, then have its receiver act on the intent when it arrives.
Hope this helps.