2016-03-03 41 views
2

好吧,这可能是陈旧的,但我真的需要了解最佳实践将是什么,而不是如何通过禁用屏幕方向或任何其他手段。即使在Android屏幕旋转时获得回调(MVP设计模式)

我有一个登录屏幕,当用户点击登录按钮时,它应该去服务器和身份验证,并返回一个响应。 我的问题是如果屏幕旋转我的片段可能没有收到响应数据的回调。

我试着在Android上的MVP设计模式。

public void registerSignInEvent(){ 
    this.signInBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      String username = usernameEdit.getText().toString(); 
      String password = passwordEdit.getText().toString(); 
      authPresenter.loginUser(username, password, 1); 
      } 
     }); 
    } 

我已经想到了以下...

  1. 使用服务办理登录到服务器,当其完成服务更新存储如is_login=falsetrue然后使用LocalBroadcastManager将事件广播到视图(片段) ,因此它可以查询presenter以了解登录状态。
  2. 使用带有setRetainIntance的片段(true);处理演示初始化和主持人将触发回调到活动中如方法onLoginSuccess //混淆自己

问题

A.我的一号思想的问题是,当我loginFragment此时暂停,广播接收器未注册,因此可能不会收到该事件。再加上我甚至不知道它是否合理。

B.它看起来复杂与MVP模式

格局真的可能没有关系,我并不真正需要的代码段寿,我只需要明白,最适合情况的过程。

注:我的演示者通过视图界面与视图(片段/活动)进行通信,反之亦然。

回答

2

无论何时接收到登录响应,您都可以尝试将用户存储在数据库/ sharedprefs中,如果发生轮换并且login-fragment被重新连接而没有收到必要的回调(这是您描述的问题)如果用户已经“已经”登录(通过检查用户是否存在于loginactivity的onResume中的db/sharedprefs中)并将用户转发到下一个活动或片段,那么可以添加一个检查。

0

首先我使用这个很酷的方法来保持主持人活着,即使活动重新创建:Presenter surviving orientation changes with Loaders。它分离并附加onStop和onStart中的活动。需要提及的是,你的第二选择与持久性片段被广泛使用,例如,通过Fernando Cejas。我通过0123'了解到clean architecture方法,他使用setRetainState(true)

而你的问题仍然让我疯狂。只有我迄今发现的解决方案是丑陋的。但它应该工作。想法:完成工作后,我检查是否附加了视图。如果是这样,我会正常进行。我没有看法,我们正处于轮换中。所以我有标志表明工作已经完成。我打开它。我也缓存任何所需的数据。等待下一个视图附加。我在哪里检查那个标志。

这里是我的代码片段。我并不以此为荣。

class SplashPresenter extends BasePresenter<SplashView> { 

    private final SplashInteractor splashInteractor; 
    private boolean isSplashWorkStarted; 
    private boolean isSplashWorkFinished; 
    private boolean isSplashWorkError; 
    private Throwable splashWorkError; 

    @Inject 
    SplashPresenter(SplashInteractor splashInteractor) { 
     this.splashInteractor = splashInteractor; 
    } 

    @Override 
    public void attachView(SplashView mvpView) { 
     super.attachView(mvpView); 
     if (isSplashWorkFinished) { 
      getMvpView().showApplicationUi(); 
     } else if (isSplashWorkError) { 
      getMvpView().showError(splashWorkError.getMessage()); 
     } 
    } 

    void executeSplashWork() { 
     if (!isSplashWorkStarted) { 
      splashInteractor.execute(new SplashInteractorSubscriber()); 
      isSplashWorkStarted = true; 
     } 
    } 

    @Override 
    public void onDestroyed() { 
     splashInteractor.unsubscribe(); 
    } 

    private final class SplashInteractorSubscriber extends Subscriber<Void> { 
     @Override 
     public void onCompleted() { 
      if (isViewAttached()) { 
       getMvpView().showApplicationUi(); 
      } else { 
       isSplashWorkFinished = true; 
      } 
     } 

     @Override 
     public void onError(Throwable e) { 
      if (isViewAttached()) { 
       getMvpView().showError(e.getMessage()); 
      } else { 
       isSplashWorkError = true; 
       splashWorkError = e; 
      } 
     } 

     @Override 
     public void onNext(Void v) { 
     } 
    } 
}