Im using MVP and RxJava similar to google-samples repo.
And I would like to ask how to correctly handle screen orientation change.
Im using MVP and RxJava similar to google-samples repo.
And I would like to ask how to correctly handle screen orientation change.
I handled by encapsulating view's state in specific ViewState class in presenter, and it is easy to test.
public interface BaseViewState {
void saveState(@NonNull Bundle outState);
void restoreState(@Nullable Bundle savedInstanceState);
}
class HomeViewState implements BaseViewState {
static final long NONE_NUM = -1;
static final String STATE_COMIC_NUM = "state_comic_num";
private long comicNum = NONE_NUM;
@Inject
HomeViewState() {
}
@Override
public void saveState(@NonNull Bundle outState) {
outState.putLong(STATE_COMIC_NUM, comicNum);
}
@Override
public void restoreState(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
comicNum = savedInstanceState.getLong(STATE_COMIC_NUM, NONE_NUM);
}
}
long getComicNumber() {
return comicNum;
}
void setComicNum(long comicNum) {
this.comicNum = comicNum;
}
}
get/set values from viewState in presenter, this helps to keep it updated, as well as presenter stateless.
public class HomePresenter implements HomeContract.Presenter {
private HomeViewState viewState;
HomeViewState getViewState() {
return viewState;
}
@Override
public void loadComic() {
loadComic(viewState.getComicNumber());
}
...
}
in Activity as View should initiate call to save and restore.
public class MainActivity extends BaseActivity implements HomeContract.View {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
homePresenter.getViewState().restoreState(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
homePresenter.getViewState().saveState(outState);
}
...
}
There is another strategy that enables saving presenter state and also
Observable
's state: retainFragment
. This way you omit standard Android way of saving data intoBundle
(which enables only to save simple variables and not the state of network requests.)Activity
:Retain
Fragment
:Notice the way activity lifecycle events are handled. When the
Activity
is created, retainFragment
is added to the backstack and on lifecycle events it is restored from backstack. retainFragment
does not have any view, it is just a holder for presenter during configuration changes. Notice the main invocation that enables restoring exactly the same fragment (and it's content) from backstack:If you are concerned about memory leaks: every time the presenter is restored presenter's view is restored:
So the previous
Activity
reference is replaced by new one.More about such handling of configuration changes here here