문제

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!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top