使用Moxy与Dagger时,屏幕旋转后视图状态无法恢复的问题
解决Moxy屏幕旋转后无法恢复视图状态的问题
看起来你遇到的核心问题大概率是Moxy注解使用冲突加上Presenter状态管理不到位导致的,结合你给出的代码片段,我整理了具体的排查和解决步骤:
第一步:修复Presenter注入的注解冲突
你的代码里同时用了@InjectPresenter和@ProvidePresenter,这两个注解在Moxy里是互斥的:
@InjectPresenter是告诉Moxy从Dagger等依赖注入容器中获取Presenter实例@ProvidePresenter是让Moxy自己通过指定方法创建Presenter
同时使用会导致屏幕旋转时,Moxy可能重新创建新的Presenter实例,直接丢失之前保存的状态。解决方案是移除@ProvidePresenter方法,只保留@InjectPresenter:
public class MyFragment extends MvpFragment implements MyView { @BindView(R.id.edittext_login) EditText mEditText; @BindView(R.id.text_view) TextView mTextView; // 只保留InjectPresenter注解 @InjectPresenter Presenter mPresenter; @Override public void changeNote(String text) { mTextView.setText(text); mEditText.setText(text); } @Override public void onCreate(Bundle savedInstanceState) { // 先执行Dagger注入,再调用super.onCreate ((MyApp) getActivity().getApplication()).getAppComponent().inject(this); super.onCreate(savedInstanceState); } }
第二步:让Presenter正确保存状态
Moxy提供了@State注解来自动处理状态的持久化,你需要在Presenter中用它标记需要保留的字段,同时在视图重新绑定的时候主动把状态同步给视图:
public class Presenter extends MvpPresenter<MyView> { // 用@State标记需要保存的状态字段,Moxy会自动处理旋转时的存储与恢复 @State private String currentNoteText; // 业务逻辑中同步更新状态 public void updateNote(String text) { currentNoteText = text; if (isViewAttached()) { getView().changeNote(text); } } // 屏幕旋转后视图重新绑定,主动把保存的状态传给视图 @Override public void attachView(MyView view) { super.attachView(view); view.changeNote(currentNoteText); } }
第三步:Dagger配置确保Presenter作用域匹配
为了避免Fragment重建时Dagger注入新的Presenter实例,需要给Presenter设置与Fragment一致的自定义作用域(比如@FragmentScope):
@Module public class MyFragmentModule { @Provides @FragmentScope Presenter providePresenter() { return new Presenter(); } }
额外检查项
- 确保你的Fragment继承自
MvpFragment(或MvpAppCompatFragment),Moxy依赖这个基类管理Presenter的生命周期和状态存储 - 确认Dagger注入时机:必须在
super.onCreate(savedInstanceState)之前完成注入,这样Moxy初始化Presenter时能拿到正确的实例
按以上步骤调整后,屏幕旋转时Moxy就能正确恢复Presenter的状态,进而同步更新视图内容了。
内容的提问来源于stack exchange,提问作者Michael Abyzov
相关产品推荐
相关产品推荐

