Loaders
monitor data source and deliver new results
After a configuration change : no need to re-query the data
I read the android guide about Loaders.
I read Alex Lockwood 4 parts tutorial . Tested his sample app too.
Tried to read the Google App for I/O 13, there's a Stream feature and reading its code find out it uses Loaders since it provides code to create a StreamLoader. Here is the Link
I suppose they use it to monitor for new data and add them to their view.
Same for Alex's app. There's an observer and when there is new data entries triggers a refresh for the UI.
So far it seems to me, Loaders are ideal choice for a "livescore" app. When there's a new update ( which means a new data entry ) it appears on your screen.
Maybe something like Twitter. New messages for you, custom Observer to notice for changes, custom Loader brings the data and an adapter to display them. No need to "pull-to-refresh".
But then again Twitter has its own RESTful API which kinda does the same job. No need for a pointer to the new data. ( don't know how they do it but I guess somehow the "push" new data to your device ).
So my question is :
Loaders are best option when we want to observe a data source and change our view so it will display the new data?
Are there any examples/app I can check dealing with that logic : monitor the data source -> get the data -> refresh UI
Any characteristic cases ( like the one with the "livescore" previously mentioned by me ) that when we have to deal with them we have to choose Loaders?
The second part of the Loaders ( configuration change, keeping the data ) I think its clear. No one want's to re-download an Image gallery when the user rotates the device.
Thank you and excuse my confusion
The best way I can describe a Loader is a Handler that is always on. Both Loaders and Handlers pass data between objects.
I agree with what you said about the "livescore" app.
The Loader monitors the source of their data and delivers new results when the content changes.
To answer your questions:
1) Loaders are best option when we want to observe a data source and change our view so it will display the new data?
A: Yes. if your data source is constantly updating. For example, like a stock-ticker app. If your data isn't constantly updating, then no, don't use a loader. For example, if your data source is only retrieved once, then there's no need for a Loader.
2) Are there any examples/app I can check dealing with that logic : monitor the data source -> get the data -> refresh UI
A: https://www.youtube.com/watch?v=3d9BeWqlfTk
Yes, they are what you want to use for the flow you're describing. Tangentially, there's also AsyncTasks and Services that have similarities.
AsyncTasks
Description (from docs):
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.)
Caution: Another problem you might encounter when using a worker thread is unexpected restarts in your activity due to a runtime configuration change (such as when the user changes the screen orientation), which may destroy your worker thread. To see how you can persist your task during one of these restarts and how to properly cancel the task when the activity is destroyed, see the source code for the Shelves sample application.
If you specifically just want a wrapper to basic threading boilerplate, use an AsyncTask otherwise I'd suggest you use an AsyncTaskLoader if you need a general purpose way to run intensive operations in an Activity or Fragment. You get the same benefits from AsyncTask, but it handles lifecycle issues for you. There are also specialty loaders, such as CursorLoader that will are made to handle specific data sources and have conveniences for interacting with certain UI elements.
Services
Description (from docs):
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 it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
You would use a service to handle data being pushed to a phone. Otherwise, the user would have to open your app to get any pushed data. Services do not interact with your UI. So a common design pattern is to use a Service to gather data from a server (whether pushed real time or if you poll) and store it in your database for use both when your app is opened or when not. There are many other use cases for Services, but this one is probably the most popular.
Conclusion
So no, you aren't required to use a Loader to load data or do long running operations on a background thread and pass the results (or progress) to your UI thread, but they are the best option for most use cases.
Related
I've been reading about how to share data between an Activity and a Service. I found some answers here and here. I'm planning on creating a singleton class as this seems like the lowest overhead mechanism to share state.
For my application, I have a service which is acquiring and logging various sensor data and is filling a data structure with the most current state, and then notifying the activity to update the UI with this info, if the activity is visible. If the activity is not visible, then when it becomes visible it consults the state information to update the UI.
I don't see any mention of whether synchronization is necessary. For instance, isn't it possible that the UI thread might be pulling data out of the structure and get interrupted by the service which then puts new data in, resulting in the UI being rendered incorrectly? Also, I want to put a flag on various pieces of data so the front end knows which pieces have been updated: the service would set a boolean and the activity would clear it. It seems like a similar problem could occur here.
Do I need to worry about this, or is it impossible for the UI thread in the activity and the (e.g.) Listener or Receiver thread in the service to interrupt each other. If they can, is it sufficient to use synchronized methods to access the data structure?
For instance, isn't it possible that the UI thread might be pulling data out of the structure and get interrupted by the service which then puts new data in, resulting in the UI being rendered incorrectly?
Possibly. A Service usually has background threads, whether you create them or you get them from specific Service implementations (e.g., the thread used by IntentService for onHandleIntent()). Synchronization is not an issue of components (activities, services, etc.), but rather an issue of threads.
If they can, is it sufficient to use synchronized methods to access the data structure?
Well, personally, I try to use synchronized objects and collections from java.util.concurrent and java.util.concurrent.atomic. Depending on what you're doing and how you're doing it, synchronized methods may be a fine solution.
I am still confused. I have read several tutorials of loaders and asynctask in Android but I can't understand some differences in some cases. For example:
Your app can't continue without the information which is provided by Asynctask or Loader
If you need information from MySQL database, what will be better?
And...What if you need information from SQLite database?
Maybe, you might need data from a url.
Your app can continue without the information which is provided by Asynctask or Loader
If you need information from MySQL database, what will be better?
And...What if you need information from SQLite database?
Maybe, you might need data from a url.
If you consider we must mention more differences or other case, you can write it.
Well, both of them are used to perform asynchronous operations, it doesn't really matter if your app can or can't continue without the information. Even if your app can continue wihtout the data, you still need to process it asynchronously to avoid an ANR message.
One reason to choose a Loader or an AsyncTask would be if you need to get data updates. The advantage of the Loaders is that they keep track of the data you are accessing and deliver new results when the data changes.
Other difference is that with Loaders you don't have to worry about configuration changes (orientation change e.g.). The LoaderManager takes care of that for you. With AsyncTask you need to take care of that yourself.
And there is even an AsyncTaskLoader, that does what AsyncTask does but with the benefits of Loaders.
The advantage of AsyncTask is that is very simple to use. If you don't need to load or monitor data, but just process something in the background. AsyncTask is still a good choice.
Cursors are simply used to reconnect to the last cursor onec it has been interrupted for a reason. They are usually designed to use in fragments or activitys.
Documentation for Loaders:
They are available to every Activity and Fragment.
They provide asynchronous loading of data.
They monitor the source of their data and deliver new results when the content changes.
They automatically reconnect to the last loader's cursor when being recreated after a configuration change. Thus, they don't need to re-query their data.
Asynctask are more likely a wrapper which contains a whole subset of methods to access the mainUI and background thread.
For what I understand, the Loader framework is geared towards accessing data stored locally in a ContentProvider / SQLite database. We have the CursorLoader class that handles this use case quite well.
But I wonder if it's practical to use the Loader framework to write classes extending Loader / AsyncTaskLoader to access remote web services (e.g. a REST web service)? I always thought that this framework is a bit too rigid and confusing (lack of proper documentation) for this use case. I prefer handling REST calls in more regular way, using AsyncTasks / Services. But recently I've found some articles that used AsyncTaskLoaders and began to wonder.
So why would anyone use Loaders to access Web Services? The only advantage I see here is that Loaders retain their results automatically. There's no Cursor here to manage afterwards.
Realistically, you probably want to use a networking library like Volley. This has some nice features like request batching and image caching. Nonetheless, for the sake of argument lets compare Service, Loaders and AsyncTask.
Services are the way to go if you want to allow the loading to continue while changing Activities or backgrounding your application. Or, if you want to export your service so multiple applications can use it. Otherwise, use a Loader or AsyncTaskLoader.
Loaders have a few advantages over AsyncTasks.
They are less likely to cause crashes by executing code after the Activity has finished, since they are aware of the android lifecycle.
The design discourages having references to Views or Activities. This reduces the likelihood of forcing the Activity to stay in memory after it has already finished.
Monitor the data source for changes and trigger callbacks when they occur
They have built in caching that can be useful after rotations. For Cursors, the CursorLoader automatically reconnects at the correct position to the last Cursor loaded
However, they also have disadvantages
The API is extremely more cumbersome than AsyncTask. Especially if you care about compatibility with older versions of Android
You are already storing UI state inside onSaveInstanceState(), so using the Loader's causes you to save state in multiple ways. This can be confusing to read and understand. Especially if you end up mixing retained fragments into the mix.
The Loader caches the loaded result, not the UI state that you actually need
I'm assuming you are just reading from web services, not writing. If you are performing updates to a web service and you need to see the service's response, then this changes things. Using an AsyncTask could prevent you from getting the response if the it is received during a rotation.
There are cases where Loader is suitable for webservices: When your server can send push notifications back to client to notify that data is changed.
If I need to asynchronously load some data via HTTP (or whatever) in order to update the UI, I have a few options when writing an Android application (among many others that I'm sure I missed):
Use a regular thread and a handler to update the UI.
AsyncTask
Use and IntentService, and use either a callback or broadcast the results via an Intent.
Using Loaders.
From what I understand, an IntentService is not tied to an Activity's lifecycle, so any changes to orientation, etc, will not impact the retrieval of data. Where this is not the case for an AsyncTask or thread fired off within an Activity.
The reason for the question, is that I just recently read about Loaders, and am confused as to their application. They seem to be more closely tied to a data source, where if the data source changes, then "transparently" everything is handled appropriately. Loaders also appear to be tolerant to configuration/orientation changes (I believe).
I've been currently using an IntentService to make RESTful service calls, and broadcasting the results to be received by appropriate Activities.
I'm assuming I could write an HTTP based Loader, but I'm not sure if this is the best use of this mechanism.
What are the advantages/disadvantages to using one of the async data loading methods over any other?
All of these mechanisms are simply options. There's no such thing as a one size fits all tool and so all of these different methods of completing the same task is a way to cover as many use cases as possible.
Ultimately, it's up to you to decide which method makes more sense for your scenario. But for a sort of generic explanation of what you should use...
Regular thread and a handler - Why when there are other, simpler, options?
AsyncTask - Since an AsyncTask will almost always depend on an Activity, use this when you need to load data asynchronously and you are 100% certain of how long it may take. Example: Executing an SQLite query.
IntentService/Service - Services are not bound to an Activity like an AsyncTask is, therefore, they are perfect for scenarios in which you may not know how long it will take to complete. Example: Downloading data from a web API and updating a database.
Loaders - Loaders are aimed at simplifying the process of loading data and populating it into UI. The nature of Loaders sort of assumes that the data you will be loading will be presented to the user as a list of some sort. Example: Downloading data and populating it into a ListView
I have a service that handles incoming data from and external source. Currently the data it recieves is forwarded to seperate DataManager that notifyAll() threads that the data has arrived. All threads check the data and the correct thread pops it off and processes it and then wait indefinitely until more data arrives. The basic idea of the thread is the class it is attached to holds all data and processing relevant towards a particular objective that may or may not be created in an Activity, but needs to be ready at any given moment.
I believe this is very inefficient and am attempting to redesign it. What I'm thinking is instead of using threads, use services and just use messenger to pass data around. Is this any more efficient or am I in the same boat?
Read this article - High-Performance Server Architecture - not saying you are doing it wrong but this might give you a new perspective.