2016-12-20 24 views

回答

5

還有就是允許保存演示狀態的另一種策略,也Observable的狀態:retain 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添加到堆棧以及從堆棧恢復的生命週期事件中。保留Fragment沒有任何視圖,它只是配置更改期間演示者的持有者。請注意,能使恢復完全相同的片段主要調用(和它的內容)從堆棧中:

setRetainInstance(true) 

如果您擔心內存泄漏:每次演示恢復演示者視圖時間恢復:

mPresenter.attachView(this); 

因此,以前的Activity參考被替換爲新的參考。

更多關於如何處理此處的配置更改here

1

我通過將視圖的狀態封裝在演示者的特定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); 
     } 
    ... 
} 
+0

感謝您的幫助。但是它可能保存像Observable一樣的定時器,例如Bundle? – MobileDev