[英]MVP and RxJava - Handling Orientation Changes on Android
還有一種策略可以保存演示者狀態和Observable
的狀態: 保留Fragment
。 這樣,您就省去了將數據保存到Bundle
標准Android方法(該方法只能保存簡單變量,而不能保存網絡請求的狀態。)
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
添加到后堆棧,並在生命周期事件中將其從后堆棧恢復。 keep Fragment
沒有任何視圖,它只是配置更改過程中演示者的持有人。 請注意主要的調用,該調用可以從堆棧中恢復完全相同的片段(及其內容):
setRetainInstance(true)
如果您擔心內存泄漏:每次還原演示者時,都會還原演示者的視圖:
mPresenter.attachView(this);
因此,以前的“ Activity
引用將被新的“ Activity
引用替代。
在這里了解有關配置更改的更多信息
我通過將視圖的狀態封裝在presenter中的特定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);
}
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.