MVP和RXJAVA-处理方向的变化Android



使用MVP和RXJAVA类似于Google-Samples repo。

我想询问如何正确处理屏幕方向更改。

还有另一种策略可以启用保存演示者状态以及Observable的状态:保留Fragment。这样,您省略了将数据保存到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没有任何视图,它只是配置更改期间演示者的持有人。请注意,从背面绘制完全相同的片段(和内容)的主要调用:

setRetainInstance(true)

如果您担心内存泄漏:每次恢复主持人的视图都会恢复:

mPresenter.attachView(this);

因此,以前的Activity参考被新的参考替换。

更多有关此类配置处理的更多信息,此处

我通过将视图的状态封装在主持人中的特定视图state类中,并且很容易测试。

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);
        }
     ...
}

最新更新