Im using MVP и RxJava похоже на google-samples repo.MVP и RxJava - изменение ориентации на Android
И я хотел бы спросить, как правильно обрабатывать изменение ориентации экрана.
Im using MVP и RxJava похоже на google-samples repo.MVP и RxJava - изменение ориентации на Android
И я хотел бы спросить, как правильно обрабатывать изменение ориентации экрана.
Существует еще одна стратегия, которая позволяет сохранить состояние презентатора, а также Observable
«s состояние: retain Fragment
. Таким образом, вы опускаем стандартный Android способ сохранения данных в Bundle
Activity
(который позволяет только сохранить простые переменные и не состояние сетевых запросов.):
public class MainActivity extends AppCompatActivity implements MainActivityView {
private static final String TAG_RETAIN_FRAGMENT = "retain_fragment";
MainActivityPresenter mPresenter;
private MainActivityRetainFragment mRetainFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
initRetainFragment();
initPresenter();
}
private void initRetainFragment() {
FragmentManager fm = getSupportFragmentManager();
mRetainFragment = (MainActivityRetainFragment) fm.findFragmentByTag(TAG_RETAIN_FRAGMENT);
if (mRetainFragment == null) {
mRetainFragment = new MainActivityRetainFragment();
fm.beginTransaction().add(mRetainFragment, TAG_RETAIN_FRAGMENT).commit();
}
}
private void initPresenter() {
mPresenter = mRetainFragment.getPresenter();
mRetainFragment.retainPresenter(null);
if (mPresenter == null) {
mPresenter = new MainActivityPresenter();
}
mPresenter.attachView(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (!isFinishing()) {
mRetainFragment.retainPresenter(mPresenter);
return;
}
mPresenter.detachView();
mPresenter = null;
}
}
Сохранил Fragment
:
public class MainActivityRetainFragment extends Fragment {
private MainActivityPresenter presenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public void retainPresenter(MainActivityPresenter presenter) {
this.presenter = presenter;
}
public MainActivityPresenter getPresenter() {
return presenter;
}
}
Обратите внимание, как обрабатываются события жизненного цикла. Когда создается Activity
, добавляется Fragment
, а на событиях жизненного цикла он восстанавливается из задней части стопы. Удержание Fragment
не имеет никакого представления, это просто держатель для презентатора во время изменений конфигурации. Обратите внимание, что главный вызов, который позволяет точно восстанавливая тот же фрагмент (и его содержимое) от backstack:
setRetainInstance(true)
Если вы обеспокоены утечкой памяти: каждый раз, когда ведущий будет восстановлен вид презентатора восстанавливается:
mPresenter.attachView(this);
Таким образом, предыдущая Activity
ссылка заменена новой.
Подробнее о такой обработке изменений конфигурации здесь here
Я обрабатывал состояние инкапсуляции вида в определенном классе ViewState в презентаторе, и его легко проверить.
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;
}
}
получить/установить значение из ViewState в презентации, это помогает держать его обновление, а также ведущие без гражданства.
public class HomePresenter implements HomeContract.Presenter {
private HomeViewState viewState;
HomeViewState getViewState() {
return viewState;
}
@Override
public void loadComic() {
loadComic(viewState.getComicNumber());
}
...
}
В представлении «Активность в виде» следует инициировать вызов для сохранения и восстановления.
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);
}
...
}
Спасибо за помощь. Но возможно ли сохранить Observable как таймер, например, Bundle? – MobileDev