After I let my user download files to cloud, I want my app to restart its loader.
Previously, onLoadFinished
is not always being called (randomly), when I wrote my code in the following way
public void reloadAfterOpenFromCloud() {
LoaderManager loaderManager = this.getLoaderManager();
loaderManager.restartLoader(0, bundle, this);
}
After referring to the discussion in Android - onLoadFinished not called, I modify my code to
public void reloadAfterOpenFromCloud() {
// https://stackoverflow.com/questions/16014992/android-onloadfinished-not-called
// This seems to be a realiable way, to make sure onCreateLoader and onLoadFinished will
// be called.
LoaderManager loaderManager = this.getLoaderManager();
Loader loader = loaderManager.getLoader(0);
if (loader != null) {
loaderManager.destroyLoader(0);
}
loaderManager.restartLoader(0, bundle, this);
}
This reduces the chance of not calling onLoadFinished
. However still, it will randomly happen, if I
- Do a clear cache, clean uninstall on my app.
- Install the app.
- Run
reloadAfterOpenFromCloud
. Again, randomly,onLoadFinished
will not be called.
When onLoadFinished
is not being called, if I run reloadAfterOpenFromCloud
again, onLoadFinished
will be called.
I'm using latest com.android.support:support-v4:25.0.0
and targetSdkVersion 25
.
I was wondering, is there any realiable workaround, to ensure onLoadFinished
is always being called, when loader restarted?
The following are part of my code snippets.
public void reloadAfterOpenFromCloud() {
// https://stackoverflow.com/questions/16014992/android-onloadfinished-not-called
// This seems to be a realiable way, to make sure onCreateLoader and onLoadFinished will
// be called.
LoaderManager loaderManager = this.getLoaderManager();
Loader loader = loaderManager.getLoader(0);
if (loader != null) {
loaderManager.destroyLoader(0);
}
loaderManager.restartLoader(0, bundle, this);
}
static class HomeMenuRowInfosLoader extends AsyncTaskLoader<List<HomeMenuRowInfo>> {
private List<HomeMenuRowInfo> homeMenuRowInfos = null;
public HomeMenuRowInfosLoader(Context context) {
super(context);
}
@Override
public List<HomeMenuRowInfo> loadInBackground() {
...
return homeMenuRowInfos;
}
/**
* Handles a request to cancel a load.
*/
@Override
public void onCanceled(List<HomeMenuRowInfo> homeMenuRowInfos) {
super.onCanceled(homeMenuRowInfos);
}
/**
* Handles a request to stop the Loader.
* Automatically called by LoaderManager via stopLoading.
*/
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to start the Loader.
* Automatically called by LoaderManager via startLoading.
*/
@Override
protected void onStartLoading() {
if (this.homeMenuRowInfos != null) {
deliverResult(this.homeMenuRowInfos);
}
if (takeContentChanged() || this.homeMenuRowInfos == null) {
forceLoad();
}
}
/**
* Handles a request to completely reset the Loader.
* Automatically called by LoaderManager via reset.
*/
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
// At this point we can release the resources associated with 'apps'
// if needed.
this.homeMenuRowInfos = null;
}
}
@Override
public Loader<List<HomeMenuRowInfo>> onCreateLoader(int arg0, Bundle bundle) {
return new HomeMenuRowInfosLoader(this.getActivity());
}
// Not being called always when restart loader
@Override
public void onLoadFinished(Loader<List<HomeMenuRowInfo>> arg0, List<HomeMenuRowInfo> homeMenuRowInfos) {
...