Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm not 100% sure based on the code you've provided, but a couple things stick out:</p> <ol> <li><p>The first thing that sticks out is that you've included this method in your <code>ListFragment</code>:</p> <pre><code>public void refresh() { mLoader.onContentChanged(); } </code></pre> <p>When using the <code>LoaderManager</code>, it's rarely necessary (and is often dangerous) to manipulate your <code>Loader</code> directly. After the first call to <code>initLoader</code>, the <code>LoaderManager</code> has total control over the <code>Loader</code> and will "manage" it by calling its methods in the background. You have to be very careful when calling the <code>Loader</code>s methods directly in this case, as it could interfere with the underlying management of the <code>Loader</code>. I can't say for sure that your calls to <code>onContentChanged()</code> are incorrect, since you don't mention it in your post, but it should not be necessary in your situation (and neither should holding a reference to <code>mLoader</code>). Your <code>ListFragment</code> does not care how changes are detected... nor does it care how data is loaded. All it knows is that new data will magically be provided in <code>onLoadFinished</code> when it is available.</p></li> <li><p>You also shouldn't call <code>mAdapter.notifyDataSetChanged()</code> in <code>onLoadFinished</code>. <a href="http://bit.ly/OjmPY6" rel="nofollow noreferrer"><code>swapCursor</code></a> will do this for you.</p></li> </ol> <p>For the most part, the <code>Loader</code> framework should do all of the complicated things involving loading data and managing the <code>Cursor</code>s. Your <code>ListFragment</code> code should be simple in comparison.</p> <hr> <h2>Edit #1:</h2> <p><strike>From what I can tell, the <code>CursorLoader</code> relies on the <code>ForceLoadContentObserver</code> (a nested inner class provided in the <code>Loader&lt;D&gt;</code> implementation)... so it would seem that the problem here is that you are implementing your on custom <code>ContentObserver</code>, but nothing is set up to recognize it. A lot of the "self-notification" stuff is done in the <code>Loader&lt;D&gt;</code> and <code>AsyncTaskLoader&lt;D&gt;</code> implementation and is thus hidden away from the concrete <code>Loader</code>s (such as <code>CursorLoader</code>) that do the actual work (i.e. <code>Loader&lt;D&gt;</code> has no idea about <code>CustomForceLoadContentObserver</code>, so why should it ever receive any notifications?).</p> <p>You mentioned in your updated post that you can't access <code>final ForceLoadContentObserver mObserver;</code> directly, since it is a hidden field. Your fix was to implement your own custom <code>ContentObserver</code> and call <code>registerObserver()</code> in your overriden <code>loadInBackground</code> method (which will cause <code>registerContentObserver</code> to be called on your <code>Cursor</code>). This is why you aren't getting notifications... because you have used a custom <code>ContentObserver</code> that is never recognized by the <code>Loader</code> framework. </p> <p>To fix the issue, you should have your class directly <code>extend AsyncTaskLoader&lt;Cursor&gt;</code> instead of <code>CursorLoader</code> (i.e. just copy and paste the parts that you are inheriting from <code>CursorLoader</code> into your class). This way you won't run into any issues with thie hidden <code>ForceLoadContentObserver</code> field.</strike></p> <h2>Edit #2:</h2> <p><a href="https://stackoverflow.com/questions/9606598/writing-data-managed-by-a-loadermanager/9607327#comment15445765_9607327"><strong>According to Commonsware</strong></a>, there isn't an easy way to set up global notifications coming from an <code>SQLiteDatabase</code>, which is why the <code>SQLiteCursorLoader</code> in his <code>Loaderex</code> library relies on the <code>Loader</code> calling <code>onContentChanged()</code> on itself each time a transaction is made. The easiest way to broadcast notifications straight from the data source is to implement a <code>ContentProvider</code> and use a <code>CursorLoader</code>. This way you can trust that notifications will be broadcasted to your <code>CursorLoader</code> each time your <code>Service</code> updates the underlying data source.</p> <p>I don't doubt that there are other solutions (i.e. perhaps by setting up a global <code>ContentObserver</code>... or maybe even by using the <code>ContentResolver#notifyChange</code> method <em>without</em> a <code>ContentProvider</code>), but the cleanest and simplest solution seems to be to just implement a private <code>ContentProvider</code>. </p> <p>(p.s. make sure you set <code>android:export="false"</code> in the provider tag in your manifest so your <code>ContentProvider</code> can't be seen by other apps! :p)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload