I have a service in my Android application that has a UI its running. The problem I am running into, it that on various devices, it doesn't seem to maintain control of the main thread. For instance, it does not ALWAYS respond to the back button being pressed. Is there a way to ensure that the service always has control of the UI?
Thanks.
Solved it! For anyone that cares, I need to called the startForeground method for the Service.
Related
I would like to run a service that gets data from an external sensor and updates the UI every second without blocking the main thread. What is the most efficient possibility to make it? Thread, IntentService, Service? Or anyting else?
Thanks in advance!
You should use a binded service if you want to update UI regularly and the activity has to access the service method.
Service vs IntentService
Check how binded service in android works in this link
I think you should use binding service.Read here.
Here are some examples:
example1.
example2
First off- Services run on the UI thread. So a service won't fix the problem of blocking the main thread. Of course getting a sensor reading is quick, so you shouldn't need to worry about it.
What else are you using the data for? If its only to update the UI, no need for a service. Just register for sensor events in your activity and update the UI when you get a sensor event. If you want to do something else, like save the data even when the app is in the background, then you may want to look at Services.
JobScheduler should be used if your app targets Android 5.0 (API level 21) or later.
I am new to Android application development. My first project is to create a tuner, which requires to record audio and analyse it in real time.
I have read a lot on background operations in Android, but I am having trouble deciding what to use:
Asynctask : Android documentation says it should be kept for short computations, but I need to analyse data for more than a few seconds.
Intentservice : Better suited for long computations, but it can't be stopped whenever I want with a button.
Worker thread : The limitations seem to be similar to that of Asynctask.
On the following link is an example I found that is similar to what I want to do. Can a worker thread still be a good choice for long computations ? Is it thread safe to use a while loop with a flag to stop the computation ?
http://developer.samsung.com/android/technical-docs/Displaying-Sound-Volume-in-Real-Time-While-Recording
Edit: I have successfully created a bound service. Inside this service, a new thread is created to update a value in a loop, which is then broadcast. But when I unbind from the service, the thread continues to run. The value will still be updated even if I close the app and restart it.
So I am back to my initial problem. How is such a thread stopped ?
Edit: Problem solved with a simple flag activated in onUnbind() that stops the loop inside the thread.
You actually want a Service, but not an IntentService. You want a Service that will run in the background and which can be controlled through Activity (and will keep working after Activity is closed). This is a common architecture for such tasks. Here is an example of open source music player for Android:
https://github.com/kreed/vanilla/blob/master/src/org/kreed/vanilla/PlaybackService.java
I have a very strange issue in an application I'm writing. It may be as simple that I am misunderstanding something about Services, AsyncTasks and when I have access to the UI thread again.
The application consists of a main activity through which you navigate to multiple other activities. The app has two Services, one that sits in the background and periodically polls while the application is in foreground, and another that runs "AACPlayer" to stream a live radio stream.
One of the activities, the one that has the UI controls for the radio, starts the service for the radio. To do this an AsyncTask is fired to grab and parse the PLS file, and finally start the Service with the proper URL of the stream. The service is started that also initiates the AACPlayer. Once the stream has started playing, a broadcast is issued that says the stream has started playing. The broadcast receiver in the activity that holds the radio controls handles the intent and updates the UI.
This works great except for one race condition where through a seemingly random combination of leaving the app or backing out of the radio screen, before the Service has broadcasted its intent to update the UI, all other activities now seem to run outside of the UI thread. Every other activity fired up during this condition receives an exception that it's in an illegal state and can not modify do anything UI related as we're not running on the UI thread. The usual culprit exception message is: W/System.err( 3818): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Has anyone else encountered that suddenly the entire application no longer is running on its usual UI Thread, and all other activities report this exception? I don't think I have any code that's doing anything illegal that would trigger this error. No UI related things inside AsyncTasks. The callback that's triggered by the broadcast receiver (receiving from the radio Service) does touch UI, but I can't think of a different way to do this?
The problem is not fixed even when the application force quits itself, but gets remedied when the application is either force quit or has its data cleared from the Android Settings.
EDIT - As requested here's some code that outlines the service being started and the activity that starts the service / controls the UI: https://gist.github.com/1080797
Any thoughts would be appreciated. Thanks.
Try moving the initialization of your PlayerServiceUpdateReceiver to onCreate(). I don't think you need to reinitialize it on every onResume(), you just need to re-register it. Do you know what I mean?
I think what is happening is that you're getting callbacks to receivers that you've overwritten with new instances.
Or I might be completely wrong and it's the correct way to do it. Correct me if I'm wrong.
I am creating an app that has a UIThread and a background thread. The background thread is basically being used as a timer - every second it sends a message to the UIThread to update the UI. When the user exits the app by hitting the backbutton, the thread continues to run. I want this to happen since the user may want to open another app while the timer continues to count down.
My question is when the user comes back to my app. I want to connect to that background thread that is running to display the current state of the app - how much time is left, etc. My question is how to hook back in to the thread that is still running in the background. I have tried using Thread and AsyncTask, but the same issue occurs.
Thanks for any help that you can provide.
Your thread is still turning by sheer chance - your application is in fact still running but it and the thread will be shut down when Android decides it needs the resources.
However what you want to do is well-provided for in Android - you need to implement a Service to have a process that runs in the background separately from your application. You can even have a Service start at boot and run whether or not your application is started.
This http://developer.android.com/reference/android/app/Service.html has most of what you need to know. To communicate between the Service and a foreground Activity you'll need to bind to a service interface, which is fortunately very easily done.
First thing that comes to mind is to change your timer thread to a Service and have apps interested in it bind to that service. Based on the Android documentation and suggested app design, you cannot depend on that thread to not be killed by the OS whenever it deems necessary.
http://developer.android.com/guide/topics/fundamentals/services.html
The android system provides a broadcast event every minute, it's call TIME_TICK.
You should:
Create a service. This is the recommended way to have a part of the app running in the background
Listen to the TIME_TICK event. This will consume less battery. (It won't wake the phone, though, so use an ALARM, too)
Add an alarm (to wake the phone if necessary)
Let the UI and the service interact. You need a callback via rpc (see the last callback example on the api page)
You should also ensure that the phone can sleep during the timeframe. You thus may want to compute the state as a delta between the starting point and now, instead of updating the state all the time.
In Android, if I want to do some background work, what is the difference between
Creating a Service to do the work, and having the Activity start the Service
VS.
Creating a standard java class to do the work, and having the Activity create an object of the class and invoke methods, to do the work in separate thread.
Doing your own threads is overkill, there are solutions for this, so you don't have to worry about the hard parts of concurrency. Have a look at AsyncTask or IntentService. If you go for a service please keep in mind that your service can be killed at any time.
Well, Android provides some useful methods for making worker threads easily. Look at the Looper class definition. It allows you to send events via a Handler to be executed one after another in another thread or transmit messages between different threads.
A service is nothing fancy. Creating a Service is just a way of telling the OS that you need to do some work even when your Activity is not visible.
Depending on the application you're building it might not be an option.
Nearly every network application will have some of its functionality on a Service to allow the user change active Activity while something is being downloaded.
In an RSS reader, for example you can click 'Update all' and, depending on the current data connection, it might take a bit longer than you wish. So if you want the user to be able to get back to the Home screen and do anything else while the files are being dowloaded you'll have to use a Service.
A Service allows you to run tasks on the background while the user is not on your Activity. This doesn't mean it'll be running all the time. Check the Service lifecycle.
BTW IntentService is a service.