I have a simple app that reads internet resource and displays the information in a widget or in listview activity in form of imageviews and textviews.
In addition to downloading the data from internet it also shows it in widget in a ViewFlipper.
When I add the widget to the home screen, it fires onUpdate immediately, downloads the data from internet and updates the widget. This works just fine. Log shows onUpdate and dataDownloaded with about 3 sec apart.
On the next update (phone has gone to sleep mode), the update doesn't happen and this is what my logs report.
onUpdate is called.
dataDownloading is called, but after 20 seconds after onUpdate has been initially called. I assume this is because the phone was in sleep and it takes time to initialize networks sockets etc.
After this, I get the ANR log entry and widget update doesn't happen, process is practically dead, widget stays on screen and doesn't respond to manual updates from within activity, which otherwise works when no ANR exception is thrown.
I'm looking for a possible solution to this. I was thinking about calling all the downloads in a different thread (from within the AppWidgetProvider, possibly using AsyncTask), store data in SQLite or local storage and doing the widget update (no downloads, just reading the data from SQLite and local storage) on the next onUpdate call. This would make the application/widget process more responsive and not fault into ANR.
Is this threading approach a bad practice? Is there an alternative? Should I use service instead? I'm inclined not to use a service, unless there's a lot of pros for it.
Sorry for the wall of text :)
Edit: From the docs http://developer.android.com/guide/practices/design/responsiveness.html
Android will display the ANR dialog for a particular application when it detects one of the following conditions:
No response to an input event (e.g. key press, screen touch) within 5 seconds
A BroadcastReceiver hasn't finished executing within 10 seconds
Threading is the only way to safely do network access on Android. So, yes, you'll need to use something like an ASyncTask or IntentService. Note that a plain Service won't be much help, since that runs on the main thread.
If you are performing a network request then you need to do so either within an AsyncTask or in a Thread/Handler combination. Here are some links to help:
AsyncTask
Painless threading
Threading
Designing for responsiveness
Thread documentation
Handler documentation
Using IntentService and a database backend is the proper way to do it I guess.
But what you never should do is performing such background tasks when the application is not active. Please only download data if your app is in foreground!
As for the widget you should use the "updatePeriodMillis" attribute. The Android system makes sure this is only executed when the widget is visible.
For more hints look at the usual location:
http://developer.android.com/guide/topics/appwidgets/index.html
Related
I have created a file observer object and it is working fine. But my requirement is to keep the file observer alive even if the app is closed manually by the user. I could have used service to keep it running but after android O that thing is not allowed anymore. Now you may say use job scheduler but I want fileObserver to fire the event as soon as the file/folder is updated.
is there any way to do so?
thank you in advance
currently you have only one option for doing this - use ForegroundService. its working just like usual Service, but it have to keep sticky Notification, which informs user that your app is working in background. as far as I know there is no listener firing when any folder content change...
you can also fire your code from time to time with AlarmManager or WorkManager, but still it may have some delay, may not fire in exact time and/or may drain battery (system will punish your app, flag as "battery drainer" and suggest user to force stop/uninstall, you can also get banned in GP Store)
I want to program an app which updates the device background every few ms (this way i want to display a gif; first idea I had any better ones?) and I wonder if this would work with a Thread or a Runnable which updates the wallpaper every few ms.
But won't the Thread or Runnable be stopped/destroyed when I leave the app?
Do you guys have any better ideas for displaying a gif file?
Backgrondinfo: I want to use a gif as wallpaper and a picture as lockscreen and the playstore apps can't handle that. (Got root proviliges to place picture as lockscreen)
Also it's a good practice for me ;)
To do this type of things, There's a separate concept called Service . Service is process which runs even after a Task is destroyed() . To know more about Service's check out devlopers.google.com
I'm trying to implement multiple tasks in my app that are required to continue running even when the app is paused (when the app loses focus but the user has not completely closed the app).
The first task consists of establishing a connection to a server and receiving updates.
The second task consists of communicating back and forth with a paired Bluetooth device.
Both tasks will not only be ran when the app is paused, they will be required to be run when the app is in focus. When the app is in focus they will be required to update the GUI based on the information they receive. Also both tasks task doesn't really have a set finishing condition except for when the user decides to stop the tasks themselves or when the app is completely closed thus they must be able to be cancelled in mid process. These two tasks will very likely be running for a long time.
In summary:
Two background tasks that can be run when app is not in focus.
Both tasks are required to be able to update the GUI when the app is in focus.
Both tasks must be able to be terminated when the user decides to stop the task inside the app or when the app is completely closed.
I believe that I need to using either a Service, IntentService or AsyncTask.
From my reading I believe that I should be using an AsyncTask but I want to be sure before starting.
Service: Can't manipulate GUI.
IntentService: Can't run tasks in parallel, they will be queued on the same thread.
AsyncTask: Seems fine!
Is this correct or should I be using a combination of things somehow?
You misunderstand the point of Service and IntentService. They are not a concurrency mechanism. They will not run automatically in the background. They run on the same thread as your app. If you need concurrency, you need either AsyncTask or Thread. Please note that if you use AsyncTask to get true concurrency between multiple tasks you still need to use executeOnExecutor().
What Services do is persist even when your Activity is gone, or when it isn't in the foreground anymore (either another activity in your app is, or another app is). So if you need your secondary thread to be running after the Activity is finished, you should have it owned in a Service. If you don't, owning it in the Activity is fine.
An IntentService is basically a Service that does more or less fixed length jobs 1 at a time. There's uses for them, but if they need to do network IO or anything like that they still have to spin off AsyncTasks, because they still are run on the main thread.
You should use a service, the purpose of a service is to have a much lesser restricted lifecycle that can run while the app isn't in the foreground. You can use a BroadcastReceiver or callback/AIDL to send messages back to the calling activity that will manipulate the ui.
I want to make my app run in the background like a process that runs always.
I need it because I want to get locations update for GPS every 2 minutes (longitude, latitude) and to use the information in a method.
For that I need for the app to be running when the phone is asleep or not in the UI of the app in other words I need the app will run always.
I'm sure that there is a way to make it , thanks anyway for any answers :)
This was just the first google search result I found:
http://www.vogella.com/articles/AndroidServices/article.html
The answer here is to use a service, if this tutorial is lacking there are 6.4 billion others.
We have something like this, but it is made up of several parts.
Firstly you will want your code to run (and be registered in the manifest) as a Service
You will probably also want to request android.permission.RECEIVE_BOOT_COMPLETED so that you can write and register a BroadcastReceiver that gets notified by android.intent.action.BOOT_COMPLETED action and its onReceive method kicks off the service.
In our case we also have a front-end activity which also pokes the service to make sure it is running, but it's been a while snce I checked to see if this was still required.
Our service is nearly empty and onCreate immediately calls a custom Handler which then manages the 'ticks' which wakes the Handler and fires a Runnable if there is work to do, but this is where my code diverges from yours. In our case we only attempt to update the GPS location when the service 'ticks' (usually every minute) and there is work to do. It usually only performs a couple of dozen operations per client per day so I can't really advise on how it will impact battery usage.
Basically I'm trying to make a little app for watching offline content. So there's a moment where the user selects to download the contents (and the app should download about 300 small files and images).
I'd like to show the user how does the process go if he enters the proper activity. Showing a list of all the files, telling what has been already downloaded, in progress or waiting for download.
My problem is that I really don't know what approach to take for achieve this. Since the download should last until finished I imagine the solution is an Service, but whats best? an IntentService, a Bound Service or an Standard Service calling a startService() for each download? And how can I keep my objects updated for displaying them later? should I use a database or objects in memory?
Thanks
I would suggest using AsyncTask class, it allows you to easily move time consuming code(like downloading files) to a different thread. This will keep your app responsive, while giving you the ability to update your UI in the process.
It's hard to be more specific without having more details about how exactly you want your app to behave. Are the downloads only going to happen when the app is running or in the background as well?
You could use Asynctask or implement a ExecutorService with custom policies and send to it the download threads.
You need to keep a reference to the AsyncTask or a Future object respectively inside of a collection if you want to give the oportunity to the user to stop downloads.
Of course, you need to call startService each time you want to download a new file.
Service onCreate only is called if service is not running and onStartCommand run each time you call startService. In onStartCommand you run a new thread for download a new file.
You can bind service with an activity and each time that your downloadsActivity is created you show the state of downloads implementing a custom Adapter. Service only finishes when you call activity.stopService or service.stopSelf