Reputation: 303
I heard loaders can help save the result of an asynchronous job during orientation changes. I have a fragment that executes a loader with some arguments. What should I do to reconnect to the loader? Important note: I don't want to restart the loader if its result was already processed by the LoaderCallbacks.onLoadFinished().
More detailed: I have a fragment with a text field. When the user inputs some text and presses Enter I should start search with a network request. I do it by starting a loader
private void loadFirstPage() {
LoaderManager loaderManager = getLoaderManager();
data.currentPage = 1;
Bundle args = new Bundle();
args.putString(VacanciesAsyncLoader.ARG_SEARCH_TEXT, data.query);
args.putInt(VacanciesAsyncLoader.ARG_ITEMS_PER_PAGE, Const.ITEM_PER_PAGE);
args.putInt(VacanciesAsyncLoader.ARG_PAGE_NUMBER, data.currentPage);
loaderManager.restartLoader(GET_VACANCIES_LOADER_ID, args, this);
}
@Override
public void onViewCreated(Bundle savedInstanceState) {
super.onViewCreated(savedInstanceState);
if (savedInstanceState == null) {
// ...
} else {
data = savedInstanceState.getParcelable(KEY_DATA);
restoreViewState(data);
reconnectLoaderIfNeeded();
}
}
private void reconnectLoaderIfNeeded() {
EnumSet<State> loadingStates =
EnumSet.of(State.REFRESHING, State.LOADING_FIRST_PAGE, State.LOADING_ADDITIONAL_PAGE);
if (loadingStates.contains(data.state)) {
getLoaderManager().initLoader(GET_VACANCIES_LOADER_ID, null, this);
}
}
And I want to reconnect to it when the screen rotates. And if I processed its result, I don't want to trigger it again.
Upvotes: 1
Views: 550
Reputation: 134664
If this is just a one-off request, the typical pattern for this should be:
Initiate the request:
getLoaderManager().restartLoader(LOADER_ID, args, callbacks);
In onCreate()
, check to see if the Loader is still running:
if (savedInstanceState != null) {
// If it exists, init with null arguments (since they won't
// be used) to reconnect the callbacks
if (getLoaderManager().getLoader(LOADER_ID) != null) {
getLoaderManager().initLoader(LOADER_ID, null, callbacks);
}
}
In your onLoadFinished()
, destroy the loader:
getLoaderManager().destroyLoader(LOADER_ID);
Assuming you've implemented your Loader
properly, this should do the trick.
Upvotes: 4
Reputation: 3889
This article helped me a lot in dealing with orientation changes regarding asynchronous tasks. It has to do with retaining Fragments:
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
Hope this helps you as it did me
Upvotes: 0
Reputation: 236
You set this code in your Activity (for fragment).
AndroidManifest.xml :
android:configChanges="orientation|keyboardHidden"
...
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden"
>
Upvotes: 0