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.
dataDownloadingis called, but after 20 seconds afteronUpdatehas 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
ASyncTaskorIntentService. Note that a plainServicewon’t be much help, since that runs on the main thread.