How do CursorLoader automatically updates the view even if the app is inactive?
I found the answer for my question. In general, CursorLoader doesn't automatically detect data changes and load them to view. We need to track URI for changes. This can be done by following steps:
Registering an Observer in content resolver through cursor using: (Done in the query method of ContentProvider)
cursor.setNotificationUri(getContext().getContentResolver(), uri);
Now when there is any change in URI underlying data using
insert()
/delete()
/update(),
we notify theContentResolver
about the change using:getContext().getContentResolver().notifyChange(insertedId, null);
This is received by the observer, we registered in step-1 and this calls to
ContentResolver.query()
, which inturn callsContentProvider
'squery()
method to return a fresh cursor toLoaderManager
.LoaderManager
callsonLoadFinished()
passing this cursor, along with theCursorLoader
where we update the View (usingAdapter.swapCursor()
) with fresh data.
For Custom AsyncTaskLoaders:
At times we need our custom loader instead of CursorLoader. Here we can use someother object other than cursor to point to the loaded data (like list etc). In this we won't be having previlige to notify ContentResolver through cursor. The application may also not have a content Provider, to track URI changes. In this scenario we use BroadcastReceiver or explicit ContentObserver to achieve automatic view updation. This is as follows:
- We need to define our custom loader which extends
AsyncTaskLoader
and implements all its abstract methods. UnlikeCursorLoader
, our Custom Loader may or may not use a content Provider and it's constructor may not call toContentResolver.query()
, when this loader is instatiated. So we use a broadcast receiver to serve the purpose. - We need to instantiate a
BroadCastReceiver
orContentObserver
inOnStartLoading()
method of abstractAsyncTaskLoader
class. - This BroadCast receiver should be defined to receive data-changing broadcasts from content provider or any system events(Like new app installed) and it has to call loader's
onContentChanged()
method, to notify the loader about the data change. Loader automatically does the rest to load the updated data and callonLoadFinished()
to update the view.
For more details refer this: http://developer.android.com/reference/android/content/AsyncTaskLoader.html
I found this very useful for clear explanation : http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html
LoaderManager.onLoadFinished is called even when the specific query doesn't match the update
The reloading is taking place because you are associating this cursor loader with the DataProvider.POST_URI
which I assume is the one you use for your posts table. Whenever there is a change in any of the elements in this table, all the cursors with that Uri
will be notified. If you want to receive notification of a single item you should implement a new Uri
scheme to match just that one item. Have a look at the documentation for the UriMatcher class for an example. You should do something similar to the PEOPLE
and PEOPLE_ID
cases.
EDIT
You can find a good tutorial on ContentProvider
here. Section 9.4 in special should be helpful in correctly implementing the ContentProvider
.
Related Topics
Copy Database File to Sdcard in Android
Android Sp VS Dp Texts - What Would Adjust the 'Scale' and What Is the Philosophy of Support
Android:Textallcaps="False" Not Working for Tablayout Design Support
Android Webview Anchor Link (Jump Link) Not Working
Open a Selected File (Image, PDF, ...) Programmatically from My Android Application
How to Disable the Recent Tasks/Apps Button
Adding Multiple Markers in Google Maps API V2 Android
Hax Kernel Module Is Not Installed
Start Android Application Without Activity
Folder Added on Android Is Not Visible via Usb
Uploading Image from Android to Gcs
Creating a Product Sdk: How to Add a Native Lib (.So) and a Jar with the Sdk I am Creating