I have one loader being used in an activity. I'm able to start the loader and it onLoadFinished is called. When I update data and call onContentChanged
in the loader i see that loadInBackground
and deliverResult
are both called. This is where the trail seems to stop. I don't receive any callback to onLoadFinished
.
If I recreate the activity (aka orientation change, or relaunch) then it will behave the same way.
I'm using the support-v4 loader and loader manager.
My SharedPreferenceLoader
based on CommonsWare's loader:
public class SharedPreferencesLoader extends AsyncTaskLoader<SharedPreferences>
implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences prefs = null;
private static final String TAG = SharedPreferencesLoader.class.getSimpleName();
public SharedPreferencesLoader(Context context) {
super(context);
}
@Override
public SharedPreferences loadInBackground() {
Log.v(TAG, "wol: load in background");
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
prefs.registerOnSharedPreferenceChangeListener(this);
return (prefs);
}
@Override
protected void onStartLoading() {
if (prefs != null) {
deliverResult(prefs);
}
if (takeContentChanged() || prefs == null) {
forceLoad();
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.v(TAG, "wol: on shared preference changed.");
onContentChanged();
}
}
Here is how the loader is being used:
public class MainActivity extends ActionBarActivity implements
LoaderManager.LoaderCallbacks<SharedPreferences> {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportLoaderManager().initLoader(0, null, this);
// fetch list of locations through an intent service.
// This will save data to shared preferences and trigger onContentChanged
MyIntentService.startActionGetLocations(this);
}
@Override
public Loader<SharedPreferences> onCreateLoader(int i, Bundle bundle) {
return new SharedPreferencesLoader(this);
}
@Override
public void onLoadFinished(final Loader<SharedPreferences> sharedPreferencesLoader, final SharedPreferences sharedPreferences) {
final List<PwStructure> locations = SharedPreferencesUtils.getLocations(sharedPreferences, this);
Log.v(TAG, "wol: on load finished: "+locations);
/* Do something with data. */
}
@Override
public void onLoaderReset(final Loader<SharedPreferences> sharedPreferencesLoader) {
}
}
Update
I found this in the LoaderManager source. It looks as if the call to onLoadFinished
isn't called if the data has the same reference.
Yes, it would appear that with the current LoaderManager implementation, SharedPreferencesLoader is pretty much screwed. I'll deprecate it.
Thanks for pointing this out!