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.
Related
Here's something interesting- How do I display information both from my content provider, and some real-time data from the web (which I don't want to save to my content provider?).
1.CursorLoader and CursorAdapter won't do IMO since I don't want to save the information to my content provider.
2.AsyncTask and updating the view in onPostExecute won't work, since right now I am displaying information from my content provider through cursorAdapter etc. and since the screen itself is an AdapterView subclass, when the loading is finished, the view might belong to some other element (recycled)
3.Service won't do for the same reason as #2 (and besides that, in this case, the background thread is coupled with the UI, so that doesn't seem like a natural solution).
**********Optional specific details starting from here if the picture isn't clear******
Say that I have some app which allows users to follow stocks.
I have a content provider, that at the path content://whatever.my.package.name/follows
has some information about which stock the user is following, whether or not it was sent to my server already (so it does have already some 'real time' data displaying through it), the parameters the user is interested in following, etc.
When displaying this information, I want to include some real time information from the web. I already have the necessary method implemented, but I can't think of a natural solution (see above). In particular, the real time data certainly cannot be saved on the same path (/follows) since this isn't a natural part of what I have in mind when I am thinking about the object "follow",but I do want to present the real time information about the stock, and it does relate to the follow presented on the screen (for example, a follow includes a start price, so we want to present the change from that start price to the real time price of the same stock etc).
I'm can't think of a good design I could use, so help will be appreciated :)
If the only thing that stops you from using the content provider is that you don't want to store the informations in it, then don't store it. Remember that a provider is just some abstraction above some data source. Nobody is going to stop you from using a in memory sqlite database for storing the live data.
Then you have two data sources and can build relations on them for displaying purposes like with sqlites attach_database or in code. Of course the live data is gone as soon as the provider is shut down so you must be able to handle that case.
EDIT
Hmm, ok. So touching the provider is a no go. You said the views are adapter views. How about using Volley or something similar to fetch the data in the adapter itself and cache it there. Whenever a view is requested (i.e in 'onBindView' when using RecyclerView) check the adapter cache for the data. If it does not exist or is outdated start fetching the data. When the request returns notify the adapter that the dataset changed. It then would start requesting views again making the next cache probe a hit. If you are fetching the data for each item in the cursor try to pass the index/position of the item to the request so that you can notify the adapter that a specific item has changed.
I have an android app in which I have a login system and some other stuff that communicate with the server. Sometimes I just get from the web server just a confirmation and sometimes I get a lot of data. So far I was using a simple database. Today I implemented a Content Provider which is working so far. To get data from the ContentProvider I used this Cursor cursor = getContentResolver().query();, but I saw that there is also the option to use a CursorLoader. What is the difference between them ? In my case what should I use ? I also saw that I have to implement it in every class the cursorLoader, can't I make a single class for it and call it when it's needed ?
As the documentation states,
CursorLoader implements the Loader protocol in a standard way for
querying cursors, building on AsyncTaskLoader to perform the cursor
query on a background thread so that it does not block the
application's UI.
This is the biggest advantage of using Loaders, i.e. it is asynchronous. Some of the other important advantages are also mentioned here.
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.
If you use the default cursors by querying the content provider directly then you need to handle closing them, and as you said you have huge data, you'd have to run the query code on a different thread. For all these purposes using CursorLoaders is much simpler and efficient. For code on how to use one, check this out.
As to your second question,
I also saw that I have to implement it in every class the
cursorLoader, can't I make a single class for it and call it when it's
needed ?
You can very well make a Base class that will be implementing the loader callbacks and then you can inherit that base class from all the classes that need to use the CursorLoaders.
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.
I've searched StackOverflow and googled but I can't find an answer.
I'm trying to build a REST-Service using Virgil Dobjanschis Designpattern B ( http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html)
I have an activity with a SimpleCursorAdapter and a LoaderManager to query a ContentProvider. This works for data in my database. Data is re-queried and UI is getting refreshed.
After every query on the ContentProvider a Thread is started to sync the requested data from network, it loads json-objects, parses and save new data to database - everything fine, but the UI is not updated.
I think I have to send my Activity a message to refresh data, but I don't know how and can't find an example how to do that.
So, what is the right way to manage this?
---- Updated ----
I think I didn't explain my problem clearly.
As you can see in this pic:
Step 7 is working. A Helper-class is updating data.
Step 7' does not happen. I thought this would be a automatic feature of a ContentProvider.
My Helper-class (Resthandler) is updating the database directly without using ContentProvider.
You have a SimpleCursorAdapter, which I suppose you use to bind data from the content provider to your UI, correct? If that's true, then you need to move the retrieved Cursor to the cursor adapter every time you update the cursor.
Do this in CursorLoader.onLoadFinished(), by calling either
SimpleCursorAdapter.swapCursor() or SimpleCursorAdapter.changeCursor().
See the Android training class
Loading Data in the Background for a complete example.
I've found a solution for this. I overloaded insert() in my ContentProvider. So I can give ContentValues to it and CP is writing data to db. CP sends notifications to Views.
It is tested and working. I have found this in a book "Programming Android".
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?