2016-03-03 45 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) { 
     } 
    } 
}