2016-12-20 3 views

ответ

5

Существует еще одна стратегия, которая позволяет сохранить состояние презентатора, а также Observable «s состояние: retain Fragment. Таким образом, вы опускаем стандартный Android способ сохранения данных в 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 не имеет никакого представления, это просто держатель для презентатора во время изменений конфигурации. Обратите внимание, что главный вызов, который позволяет точно восстанавливая тот же фрагмент (и его содержимое) от backstack:

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