I'm wondering if an Android Loader (more specifically AsyncTaskLoader) is the correct job for asynchronously submitting data to a web service.
The way I see it, most of the examples deal with grabbing data and displaying it to a user. For such operations things like having it "accidentally" hit the URL endpoint twice, or caching data is the norm.
However, when we're dealing with submitting data we want a way to absolutely make sure that:
the data is only submitted once
the submit operation is done anew each time we call it
we can pass a result back that will notify the user that the action was successful (or failed)
So, with that being said, how would I go about using the Loader pattern to send data in an asynchronous fashion? Are there any examples that exist for this type of use-case? Or is a Loader not the right thing, and I should be using something else altogether?
I don't agree with Nikolay on this one (I know how it sounds with my reputation against his;)). I use Loader (AsyncTaskLoader) to write data as well. More specifically I have an AsyncTaskLoader which checks for data on-line and then writes it to local database. It works like a charm and doesn't have AsyncTask drawbacks when it comes to persistence and leaking problems.
And it has the thing which you need (probably needed) - it doesn't run twice e.g. on configuration change, because it reconnects to the existing loader.
What you need to do is to put your submitting code in the loadInBackground() method and you're home.
You are probably looking for AsyncTask. The loader caches data internally and returns it to the app to be displayed by the app, it is not really designed to submit data. Why do you think you need to use a Loader for this?
Related
I'm new to Android Development, and I've run into this problem that I haven't found a solution for.
It starts off first with going to a webservice api for login. From there if the login is successful it executes to 2 functions for the actually data it needs, stores in sqlite and then proceeds to next activity. All 3 api requests are using AsyncTask and from what I understand my Activity is actually running faster than my "doInBackground" background thread. I want to know the path or what i should look into. I've read posts about using sleep, and read posts about how that is bad to do. I want to get the json data i need, store it, and use it immediately. I think i'm suppose to find away to connect directly and use a progress bar to get the data. Keep in mind, it's not a lot of data, but it's enough to stall my application.
Not sure what a ProgressBar has to do with retrieving data from a server but if you're looking for AsyncTask alternatives (particularly for HTTP calls) you can look at these frameworks (you'll probably only want to pick one):
Square's Retrofit
Google's Volley
Either one will make your life a lot easier when it comes to making HTTP requests. Their own documentation explains how to use them pretty well so I'm not going to go into how to use it here.
If you're looking for a native, lower level AsyncTask alternative, have a look at AsyncTaskLoaders. The AsyncTaskLoader essentially does exactly the same thing as an AsyncTask but they live within the life cycle of the Activity or Fragment so your code tends to be less error prone.
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.
If I do need it, I'll have to modify about 15 classes (models and model-manager classes), so I really want to know if I need a ContentProvider.
Here's where I am:
Similar to Twitter, I'm getting rows of data from a server, and saving it locally in case the user has no Internet connection. But the ideal way is to always get it from the Server.
I am probably not going to use SimpleCursorAdapter because the rows of data I get from the server includes URLs, which means I have to create a custom adapter to display images.
I need to load data into the ListViews asynchronously because I'm having a ViewPager with 3 Fragments that shows the same data (different filters tho), so, since a ViewPager loads 3 Fragments into memory, it means 3 queries are executing (and that's most likely the cause of non-smooth swiping).
So far, the way I synchronize data between the App and the Server is:
Fragment.onStart() executes an AsyncTask which returns rows of data formatted as JSON data
Said AsycTask.onPostExecute() updates the List<E> and calls Adapter.notifyDataSetChanged()
The issue here is that each time I change tabs, the onStart() is called, ergo the AsyncTask executes causing the UI not being smooth.
Should I change the way I synchronize data with the Server, or should I use ContentProvider?
EDIT: as a head up, the reason I'm asking is that startManagingCursor() method is depracated. It says to use the Loader framework, but it seems it's only available through ContentProvider
You don't need to develop your own provider if you don't intend to
share your data with other applications. However, you do need your own
provider to provide custom search suggestions in your own application.
You also need your own provider if you want to copy and paste complex
data or files from your application to other applications.
from http://developer.android.com/guide/topics/providers/content-providers.html
I wrote a custom CursorLoader based on the SimpleCursorLoader source code that comes within the support library. You can search this site for more information about writing a custom one.
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'm getting hung up on how to handle the data for an app I'm designing. I want to pull a list of items from the net. The data is updated routinely, and I think it would be good to store all the data on the device so the app can load quickly and refresh the data in a background thread rather than have to wait for the network on every start-up.
I think I should make the data available in an XML and have a thread parse and save into a SQLite DB, but I'm not sure if that's the "best practice." Are there other ways that people go about handling this?
The cleanest way (or at least, I think it is the cleanest way) is to implement a custom ContentProvider class that interfaces with your server. You can query the contenprovider and if it doesn't have the data in a local cache (for example a SQLite db as you said) it downloads it from your server and adds it to the local data. Why a content provider? because then you can easily access your data across apps and you have a nice and clean way to get your data when using intents.
Also, I personally prefer not to download data when the app is not running, because it will cost battery life while the user does not actively requests the data.
Sounds reasonable.
If the download of the new data takes more than some seconds, you might want to use a Service. This will allow you to continue the update even when the user has left your app.
Also, think about how you will notify the user that something is going on. Displaying some progress indicator is always a good idea. Otherwise, users might just think the data is not up to date because the app is broken.