I am a little new to android development. I know that network activity and expensive operations should not be done on the ui thread, but what about database activity?
I have an activity that, when started, I query an sqlite database and dynamically populate rows in a tablelayout with an inflator. I do this all in the oncreate() method. Should this be done in a separate thread? If so, can anyone provide me with an example?
Thanks!
Depending on the database and the device, querying a database on the UI thread could possibly trigger an ANR message.
Android provides an easy way to perform asynchronous queries so you don't end up block the UI thread if it takes longer than expected. Check out the AsyncQueryHandler in the docs and the IOSched has an implementation you can steal and use.
I wouldn't expect a local query to really slow the UI down much. Do you notice any hang when you first start the app? Things like fetching URLs over the network should be in their own thread because they can cause long hangs.
Related
I have the following design:
Activity/FragmentA upon a user action starts an AsyncTask to fetch a set of data.
While the AsyncTask is running, a progress indicator is displayed to the user.
When the AsyncTask finishes its task and fetches the resultset, it saves it in a singleton class serving as a shared datamodel.
When FragmentA is notified that the AsyncTask has finished (LocalBroadcastReceiver) then it start ActivityB/FragmentB which takes the set of results from the shared singleton and displays them in a ListView.
This works but since I am a newbie in android I am trying to understand and learn best practices.
E.g. I see a small delay from the time the progress bar is dismissed to the time the UI of ActivityB/FragmentB is displayed (during this latency the UI of ActivityA/FragmentA is still visible).
Also I think that somehow if the fetch of the items was done from FragmentB instead of FragmentA would make FragmentB "autonomous"
Overall can someone please help me understand how could I have implemented this differently using better/standard practices in android and the pros/cons of each approach?
Fragments
Fragments are small part of the activity which has their own life cycle, which provides developer more flexibility to deal with UI. Fragments has nothing to do with background processes.
Now your main question is about the background processes.
AsyncTask
This is nothing but the bit better version of thread with some predefined callbacks, when u need to perform some network operation which will take not more than 20 seconds, and after that it refreshes the UI, its better to use asycntask. Do not use Services (Avoid complexity, Keep it simple). You can use some third party library also.
IntentService
Now IntentService are better version of service, the main purpose of IntentService is to avoid performing long running operations on mainthread and provide queueing system to the developer. You should use services if you do not need user interaction while running long running operations (e.g syncing app with the server at the end of every day).
So for conclusion
User Interaction + short running network operation = AsyncTask
No User Interaction + long running network operation = IntentService + Broadcast Receiver to notify UI of needed
I know there are a lot of threads relating to this topic on here, but I haven't read a real answer to my question, and a lot of them are from 2010 when there didn't seem to be as much emphasis on keeping tasks off the UI thread.
I need to make a database query that is just intensive enough that it causes a noticeable delay in UI response (on my S5, so it'd be worse on a lot of phones). I want to push the query to another thread. I've been doing so with ASyncTask, but I'm reading that there are issues with ASyncTask and things like the screen rotating, interrupting apps, and memory leaks. The recommendation I see everywhere is to use a CursorLoader, but the constructor for that requires a Uri because it's designed for content providers. Not only does a content provider seem like a bit of overkill for my app, but the content provider tutorial page from Google specifically states "You don't need a provider to use an SQLite database if the use is entirely within your own application."
So my question is what, if anything, lies between ASyncTask and a Content Provider? Is there any implementation of CursorLoader for internal databases? Maybe a more robust implementation of ASyncTask?
I've been doing so with ASyncTask, but I'm reading that there are issues with ASyncTask and things like the screen rotating, interrupting apps, and memory leaks.
AsyncTask is a bit tricky to use properly. Having one be managed by a retained fragment (e.g., a model fragment) helps.
Is there any implementation of CursorLoader for internal databases?
None that work well. I say this having written (and since deprecated) one. The Loader interface is an abstraction designed around a singular use case: ContentProvider.
Maybe a more robust implementation of ASyncTask?
It's not that AsyncTask needs to be "more robust", but that you have to be aware of the various problems with it. For example, the vaunted CursorLoader uses an AsyncTask.
At the end of the day, all AsyncTask does is use a background thread from a thread pool and mediate communications back to the main application thread for the results of the work. There are any number of ways of accomplishing the same end. Presently, I'm fond of using greenrobot's EventBus (or one from a thread pool, if there might be lots of simultaneous events), in conjunction with an ordinary thread. Beyond that, you can:
Use an ordinary thread with a Handler
Use an ordinary thread with post() on a View
Use an ordinary thread with runOnUiThread() on an Activity
And all of those presume that the work is reasonably short and disposable, as would appear to be your case. For longer and/or less-disposable bits of work, use an IntentService, possibly my WakefulIntentService if the work might take dozens of seconds or more.
However, all of these still have issues, in some cases the same issues that AsyncTask itself has (e.g., addressing configuration changes properly). There is no "silver bullet".
I'm developing an app which must heavily interact with the server.So user input name and password and after authorization the next tasks must be performed:
The app has to fetch all incoming and outcoming messages for this user and load them to SQLite database.
Fetch all user friends (JSON with id,names,contact_data) and also load it to the app's database
Jump to the next activity and display income messages from the local database.
The problem this operations are too slow and when app starts new activity it is nothing to fetch from the database :AsyncTasks have not completed yet.I'm forced to use AsyncTask.get() in order to wait when they all complete but this takes over 16 seconds to wait!So what should I do: use threads, or before loading fetched data to database hold it in memory and display it in the new activity instead of fetching it from the database?But even without database tasks other fetching tasks take nearly 10 seconds to wait!So what should I do?
Oke a couple of things going pretty wrong here.
Do not use AsyncTasks for Networking. Use a service. In short, this is because your AsyncTask will stop, as soon as the Activity that started it will stop. This means that network requests get aborted easily and data goes lost and has to re-start again when the Activity is opened again.
Do not use .get() on AsyncTasks. This makes the UI thread wait for the task to complete, making the whole AsyncTask idea kinda useless. In other words: This blocks your UI.
What you should do:
Read up on using services. You can also have a look at a great opensource library called RoboSpice to help you with this.
Stop using .get() on AsyncTasks, if you want to know when it is done just use a listener.
Execute AsyncTasks on a threadpool ( myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); ) when possible.
You should use a Service. This way it always can complete the tasks it was doing and you can complete all your tasks. Besides that you should initialize the app once, and after that only update the data.. that can't take 10 seconds.. than you're having an other problem.. But the nice thing of the service is that this can run in the background. see: Services in Android Tutorial
== Edit
Also take a look at GreenDao This library arranges fast SQlLite operations. Without the large setup!
AsyncTasks are not meant to run several small tasks concurrently at the same time. Quoting the docs
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
Use Threads in a ThreadPool when you want to run multiple tasks concurrently.
How you want to handle this situation is up to you. When the background tasks take too long, you can always show an alert dialog to the user and then take them to the activity once the data has been populated. Many apps show a 'Loading' screen when this happens. You can also show the 'Loading' Spinner control if no data is available yet. Never show a blank screen.
If the server side calls are under your control, employ some sort of caching to speed up the time. Any API call that lasts more than a second will make for an impatient user. If not employ one of the techniques mentioned in the previous paragraph. #Perception's technique is also one to consider if you can do it.
For android I am trying persist state if onDestroy() is called. I'm wondering what are common design patterns used to do such a thing so that the actual app functionality is decoupled from the persistence functionality? For example, I have a for loop that iterates through all of the players in the game. This update happens at the end of each round in the game. Would it be possible that the app gets destroyed half way through the update? If that happened, what kind of logic would i need to include to remember which player was updated.
You have two main options for saving state. If you are concerned with instance variables, then override Activity.onSaveInstanceState The answer to this question provides a good sample of how to do this.
For persistent data, you can either store it in SharedPreferences, the SQLite database, or write it to a file. This article should help you get started: http://developer.android.com/reference/android/app/Activity.html#SavingPersistentState
Your app can be killed half way during the update if users switch to another app such as receiving a phone call.
Considering such cases, you may need to persist your state in onPause() instead of onDestroy() since onPause() is the last method which is guaranted to be called when your activity is killed by the system.
And in onPause(), you can start a background service to do the update which can give your process higher priority so that it's less likely to be killed by the system when you are doing the update.
See more details in the Activity lifecycle and the Process document.
Android is not very nice about killing apps. You may or may not get onPause or onDestory. You may or may not be able to receive a hook onShutdown of the VM. Basically your app can die at any time (low memory pressure), user kills it, or etc and you won't get any warning. Basically it is best practice to assume that you can die at ANY time and store or update critical state as soon as you get it.
Basically I would either make a SQLitedatabase or use shared preferences for this.
Can someone tell me the TRUE difference?
My rule of thumb is that an AsyncTask is for when I want to do something tied to single Activity and a Service is for when I want to do something that will carry on after the Activity which started it is in the background.
So if I want to do a small bit of background processing in the Activity without tying up the UI I'll use an AsyncTask. I'll then use the default Handler from that Activity to pass messages back to ensure updates happen on the main thread. Processing the updates on the main thread has two benefits: UI updates happen correctly and you don't have to worry so much about synchronisation problems.
If for example, I wanted to do a download which might take a while I'd use a Service. So if I went to another Activity in my application or another application entirely my Service could keep running and keep downloading the file so it would be ready when I returned to my application. In this case I'd probably use a Status Bar Notification once the download was complete, so the user could choose to return to my application whenever was convenient for them.
What you'll find if you use an AsyncTask for a long-running process it may continue after you've navigated away from the Activity but:
If the Activity is in the background when your processing is complete you may have problems when you try to update the UI with the results etc.
A background Activity is far more likely to be killed by Android when it needs memory than a Service.
Use Service when you've got something that has to be running in the background for extended periods of time. It's not bound to any activity. The canonical example is a music player.
AsyncTask is great when some stuff has to be done in background while in the current activity. E.g. downloading, searching for text inside a file, etc.
Personally I use Handlers only to post changes to the UI thread. E.g. you do some computations in a background thread and post the result via handler.
The bottom line: in most cases, AsyncTask is what you need.
To complement the other answers here regarding the distinction between service and AsyncTask, it is also worth noting[0]:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
Services tend to be things that describes a significant part of your application - rather than an AsyncTask which is typically contributes to an Activity and/or improves UI responsiveness. As well as improving code clarity Services can also be shared with other applications, providing clear interfaces between your app and the outside world.
Rather than a book I would say the developer guide has lots of good answers.
[0] Source: http://developer.android.com/reference/android/app/Service.html#WhatIsAService
AsyncTask: When I wish to do something without hanging the UI & reflect the changes in the UI.
E.g.: Downloading something on Button Click, remaining in the same activity & showing progress bar/seekbar to update the percentage downloaded. If the Activity enters the background, there are chances of conflict.
Service: When I wish to do something in the background that doesn’t need to update the UI, use a Service. It doesn’t care whether the Application is in the foreground or background.
E.g.: When any app downloaded from Android Market shows notification in the Status Bar & the UI returns to the previous page & lets you do other things.
Service
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with.
When to use?
Task with no UI, but shouldn’t be too long. Use threads within service for long tasks.
Long task in general.
Trigger: Call to method onStartService()
Triggered from: Any Thread
Runs on: Main thread of its hosting process. The service does not create its own thread and does not run in a separate process (unless you specify otherwise)
Limitations / Drawbacks: May block main thread
AsyncTask
AsyncTask enables the proper and easy use of the UI thread. This class allows performing background operations and publishing results on the UI thread without having to manipulate threads and/or handlers. An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread.
When to use?
Small task having to communicate with main thread
For tasks in parallel use multiple instances OR Executor
Disk-bound tasks that might take more than a few milliseconds
Trigger: Call to method execute()
Triggered from: Main Thread
Runs on: Worker thread. However, Main thread methods may be invoked in between to publish progress.
Limitations / Drawbacks:
One instance can only be executed once (hence cannot run in a loop)
Must be created and executed from the Main thread
Ref Link