I have a service which reads data from a Socket connection and during peak hours. The frequency of the changes is every five seconds.
I have two options in mind.
Update the List, using a BroadCastReceiver.
Create a new Thread in the Activity where I created the List, read a static variable every five seconds, and when the change occurs, change the static variable from the Service.
Which option is more efficient and what are the pros and cons of both?
If you think there is a better option, please let me know.
Thank you.
I would use the BroadcastReceiver (with the LocalBroadcastManager) option. I would recommend you to make your model class implement Parcelable. I would definitely avoid the solution 2
BroadCastReceiver will be efficient for your case.
It will help you to update your ListView when it receives new data. So you don't need to check for update in every 5 seconds.
It will increase the performance of your App. On the other hand in case of very frequent updates it will not wait for the given interval.
So go with broadcastreceicer.
Here is the pros that you will get from BroadcastReceiver :
A Broadcast receiver wakes your application up, the inline code works only when your application is running.
For example if you want your application to be notified of an incoming call, even if your app is not running, you use a broadcast receiver.
If your application is playing audio, and you want to stop the music on an incoming call, you use the inline code.
With broadcast receiver you can't uptade the UI, you can see WHY here, if you talk about other thing, explain us please... In that post you can see a other method to update UI from intent service, and I think is the best way to update UI from intent service because you only update UI when you need it and you don't overcharge the app process .
Finally if you want to update your UI every 5 seconds do it but with a little difference... I would do update every 5 seconds my UI if my app is in first plane if isn't it then update my app when app comes to first plane in OnResume() method because you don't use extra memory from device when my app is in background...
Tell me if I helped you and good programming!
Related
I would like to know, I have an Activity that receives broadcasts from an IntentService that needs to save data and then export it to a CSV file. However, this can take longer than 10 seconds, and I know there are certain problems with starting AsyncTasks and Threads using BroadcastReceivers that they might get killed after 10 seconds. I would like to know, how would I overcome this?
EDIT: Note that what I am actually doing is saving data from sensors, calculating data, and then exporting. Apparently when the app is in the stopped state when receiving the save command from the other app, the app gets stuck in the calculation state. The save and export use AsyncTasks, but the calculation uses a Thread where I send a message back to the Activity using a Handler. Does anyone know how I would get around this? I used PendingResult in the saving portion, but now it gets stuck in the calculation portion.
Have it launch a Service to do the work, rather than doing it in the Receiver itself.
Here are different approaches to save data in background.
Android background processing
It really depends upon your requirements. If exporting to csv can tolerate a little bit delay, use WorkManager as its battery friendly and automatically uses best approach depending upon API level.
Use foreground service, if you want immediate high priority background execution and you also wanna notify user because foreground services are visible to users via a non-dismissible notification in the notification tray. For example, WhatsApp attachment uploading.
If it is not a very long running background task and you don't expect user to close the app during this, you can use any background execution approach like ASyncTask, Rxjava, kotlin Coroutines.
background execution evolution. A very interesting article to read and compare these different approaches.
I figured out a solution. As suggested, I used a foreground service, however, there was an issue with my callback to my activity in my background thread that was started by the service that the callback interface was null when the app was paused. I was able to fix that.
Thank you for your help.
I started learning android i've been playing with it and so far so good but i have some doubts about Services, i started learning them today so by gently if a say something very wrong.
For example, i want my app to grab some information over the internet from time to time, this polling period is defined by the user, then the UI gets updated. I though about creating a Service that run lets says every 30 minutes, gets the information and updates the UI.
If i get it right:
An IntentService just executes an operation and stops by itself sending the result through an intent(right?), so i think it's not what i want.
A Bounded Service is most likely used when you want IPC or allow binding from external apps, which again i think it's not what i want.
I think a Local Service is probably what i need, using a LocalBroadcastReceiver to update the UI, how can i make it to run the operation every X minutes( Handler postDelayed, ScheduledExecutorService or Alarm Manager ? )
If i understand it right a Service if not bounded can run infinitely if it's not killed due to low memory problems, making it a foreground Service is the safest ?
Last thing and it's kind of a noob doubt, if the user leaves the application(Click Home Button or opens other app) the app is still in background but the activities are in "Paused" or "Stopped" mode will the Service still be able to talk to them ?
Sorry for long post and thank you.
Your requirement : after every x minutes, start a service, pull some date, update UI.
Solution :
Define or set an alarm for every x minutes, to trigger a receiver.
From receiver start the service.
In the service, start an async task to fetch the data in doInBackGround().
Once data is fetched, from onPostExecute() send a broadcast to your activity.
In the activity have a dynamic receiver registered for broadcast sent from service.
From dynamic broadcast receiver update UI.
From what you've explained I wouldn't personally use a service.
The Android docs on services explain more but here is a snippet:
http://developer.android.com/guide/components/services.html
A Service is an application component that can perform long-running operations in the background and does not provide a user interface.
You could perhaps looks at using an AsyncTask, especially given that you only want it to run whilst the app is running:
http://developer.android.com/reference/android/os/AsyncTask.html
This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
There is a good answer here on how to run an AsyncTask repeatedly at specific time intervals: How to execute Async task repeatedly after fixed time intervals
this scenario is very common according to the Android documentation but still I don't find a straight solution neither there nor anywhere on the net.
So I have a service that should do something like this:
Register a LocationListener to receive the user location
Once the LocationListener is called - stop listening for a 5 minutes
After 5 minutes start listening again and loop from 1
This is the recommended way to save battery power while listening for the user location.
As a service I have a major problem with step 3.
The only way I found to "wait" for 5 minutes is to schedule a java.util.Timer to execute a TimerTask in 5 minutes and this TimerTask should register the LocationListneres again.
However this does not work because of:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Which is also expected because requestLocationUpdates should be called from a "main" thread.
Ok .. nice... but I don't have a Main thread. I don't have an activity. From the TimerTask I can't send an intent to the service to register my listeners back.
How can I ask my own service to register my listeners again?
This is the recommended way to save battery power while listening for the user location.
Really? The only way that's a good pattern is if you are using AlarmManager for the five-minute delay, so the device falls asleep in between location checks.
The only way I found to "wait" for 5 minutes is to schedule a java.util.Timer to execute a TimerTask in 5 minutes and this TimerTask should register the LocationListneres again.
And that would be a horrible use of battery, because it would mean you would need to keep the device powered on constantly, not allowing it to go to sleep.
I don't have a Main thread
Yes, you do. All processes have a main application thread. onCreate(), onStartCommand(), etc. of a service are called on the main application thread.
I don't have an activity.
Then you better write one, as your app will not work on Android 3.1+ without it. Your app will not run until a user launches one of your activities on Android 3.1+.
How can I ask my own service to register my listeners again?
What you are trying to accomplish is a rather complex problem. Not only do you need to arrange for the device to fall asleep and wake back up again, but you also need to deal with lots of edge cases (e.g., what if no location is available, because the device is in airplane mode or is underground or something?).
I wrote LocationPoller to handle your use case, and another developer forked it to create a more feature-rich implementation.
Whether you use one of these directly or simply examine their implementation, they should be useful to help you understand how to solve this problem. All of the details, though, are well beyond the scope of a StackOverflow answer -- it would take several pages in a book to explain it all.
You can specify the parameter in requeestLocationUpdates() to make it run after a certain time.
I am developing an android app which fetches/uploads data from/to the web service every n minutes. This upload/download is only done when the app is running. But this might change in future.
I dont update the UI when the new data is downloaded. The UI is only updated if the user is on the current screen(app have multiple activities)
My question is what is the best approach to this problem.
I dont think service is the right approach as it sounds like an overkill(in the present scenario). AlarmManager could be an option.
Running threads inside a service be an option ..something like this .
Any pointers/suggestions would be great.
Thanks
I am using AsyncTask in my activity to ask .net web service some information and it works and easy to use.
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
Well, in this case, since the app would already be running during the time, either would work great, but a service can be called from anywhere within the application so this is where I would use the service over the thread.
If you want to create the thread to only be used in lets say Main.java, then thread would work fine, these are the only things that I can see really making ANY difference at all, they're really pretty close, and in this case neither gives a distinct "correct" answer, but I would choose Service
I think all approaches you noted would work ok. Personally I'd go with this:
Use AlarmManager to wake download service. Start it when Activity is shown, stop it when activity hidden.
Download service should be short lived: start it to do the upload/download and then shut it down.
If download service does get some new data, it sends a Broadcast which Activity listens to.
Just broadcast a message after your upload/download is done, and then have a receiver start the service and then have that service stop itself. And you are done.
This should be done if you dont plan on polling the server for new information or anything. Primarily this kind of approach would be for onetime update, interpret, finish. And wait until the next update. Which primarily for most cases is streaming.. but depends on what you are getting.
I am having some design techniques about How shall I schedule a code to retrieve the weather info?
Should I use alarms to retrieve the weather each 10 minutes?
And do I need to run a service for this? Or just put the code in the Broadcastreceiver and start when the alarm fired?
This is a good question. Yes, you will need to put this code in either a service or broadcastreceiver because when and activity loses focus (meaning the user is using a different app or the phone is asleep) they pause and/or close. However, i have no experience with either Services or Broadcastrecievers, so that is as much as i can tell you.