这是我第一次使用Fragments处理Google Lifecycle Architecture组件 . 我的应用程序使用带有BaseViewModel的MVP来保持Presenter跨配置更改 .

在我的活动中,按照Lifecycle组件的预期,为Presenter调用所有Activity生命周期事件;但是,没有任何Fragment Presenters的生命周期事件被调用 .

代码时间!

BaseViewModel.java

public final class BaseViewModel<V extends BaseContract.View, P extends BaseContract.Presenter<V>>
        extends ViewModel {

    private P presenter;

    private static final String TAG = "[" + BaseViewModel.class.getSimpleName() + "] ";

    void setPresenter(P presenter) {
        Log.d(APP_TAG, TAG + "setPresenter presenter: " + presenter);
        if (this.presenter == null) {
            this.presenter = presenter;
        }
    }

    P getPresenter() {
        Log.d(APP_TAG, TAG + "getPresenter presenter: " + presenter);

        return this.presenter;
    }

    @Override
    protected void onCleared() {
        Log.d(APP_TAG, TAG + "onCleared ");
        super.onCleared();
        presenter.onPresenterDestroy();
        presenter = null;
    }
}

BaseFragment.java

public abstract class BaseFragment<V extends BaseContract.View, R extends BaseContract.Repository, P extends BaseContract.Presenter<V>>
        extends Fragment implements BaseContract.View {

    private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
    protected P presenter;

    @SuppressWarnings("unchecked")
    @CallSuper
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //Initializes the ViewModel
        BaseViewModel<V, P> viewModel = ViewModelProviders.of(this).get(BaseViewModel.class);

        boolean isPresenterCreated = false;

        if (viewModel.getPresenter() == null) {
            viewModel.setPresenter(initPresenter());
            isPresenterCreated = true;
        }

        presenter = viewModel.getPresenter();
        presenter.attachLifecycle(getLifecycle());
        presenter.attachView((V) this);
        presenter.setRepo(initRepository());

        if (isPresenterCreated) {
            presenter.onPresenterCreated();
        } else {
            //Hacky workaround I don't want to use
            presenter.onPresenterRestored();
        }
    }

    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }

    @CallSuper
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        presenter.detachLifecycle(getLifecycle());
        presenter.detachView();
    }

    protected abstract P initPresenter();
    protected abstract R initRepository();

}

BasePresenter.java

public abstract class BasePresenter<V extends BaseContract.View> implements LifecycleObserver, BaseContract.Presenter<V> {

    private Bundle stateBundle;
    private V view;
    private BaseContract.Repository repo;

    @Override
    final public V getView() {
        return view;
    }

    @SuppressWarnings("unchecked")
    @Override
    final public BaseContract.Repository getRepo() {
        return repo;
    }

    @Override
    final public void attachLifecycle(Lifecycle lifecycle) {
        lifecycle.addObserver(this);
    }

    @Override
    final public void detachLifecycle(Lifecycle lifecycle) {
        lifecycle.removeObserver(this);
    }

    @Override
    final public <R extends BaseContract.Repository> void setRepo(R repo) {
        this.repo = repo;
    }

    @Override
    final public void attachView(V view) {
        this.view = view;
    }

    @Override
    final public void detachView() {
        view = null;
    }

    @Override
    final public boolean isViewAttached() {
        return view != null;
    }

    @Override
    final public Bundle getStateBundle() {
        return stateBundle == null
                ? stateBundle = new Bundle()
                : stateBundle;
    }

    @CallSuper
    @Override
    public void onPresenterDestroy() {
        if (stateBundle != null && !stateBundle.isEmpty()) {
            stateBundle.clear();
        }
    }

    @Override
    public void onPresenterCreated() {
        Log.d(APP_TAG, "BasePresenter.OnPresenterCreated");
    }

    @Override
    public void onPresenterRestored() {
        //Hacky
        Log.d(APP_TAG, "BasePresenter.onPresenterRestored");
    }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_START)
    void onStart() {
        if (isViewAttached()) {
            onStartWithAttachedView();
        }
    }

    public void onStartWithAttachedView() {

    }
}

我正在测试的碎片: GameSituationsFragment.java

public class GameSituationsFragment extends BaseFragment<GameSituationsContract.View,
        GameSituationsContract.Repository, GameSituationsContract.Presenter>
        implements GameSituationsContract.View {
    @BindView(R.id.gs_prev_session_button)
    ImageView prevSessButton;
    @BindView(R.id.gs_next_session_button)
    ImageView nextSessButton;
    @BindView(R.id.gs_selected_session)
    TextView selectedSessionText;

    private static final String TAG = "[" + GameSituationsFragment.class.getSimpleName() + "] ";

    private InteractionListener interactionListener;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) return;

        if (activity instanceof GameSituationsFragment.InteractionListener) {
            interactionListener = (GameSituationsFragment.InteractionListener) activity;
        } else {
            if (BuildConfig.DEBUG) {
                throw new RuntimeException(activity.toString()
                        + " must implement GameSituationsFragment.InteractionListener");
            } else {
                //Todo what do we want to do?
                Log.e(TAG, activity.toString() + " must implement GameSituationsFragment.InteractionListener");
            }
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof GameSituationsFragment.InteractionListener) {
            interactionListener = (GameSituationsFragment.InteractionListener) context;
        } else {
            if (BuildConfig.DEBUG) {
                throw new RuntimeException(context.toString()
                        + " must implement GameSituationsFragment.InteractionListener");
            } else {
                //Todo what do we want to do?
                Log.e(TAG, context.toString() + " must implement GameSituationsFragment.InteractionListener");
            }
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_game_situations, container, false);
        ButterKnife.bind(this, view);

        return view;
    }

    @Override
    protected GameSituationsContract.Presenter initPresenter() {
        return new GameSituationsPresenter();
    }

    @Override
    protected GameSituationsContract.Repository initRepository() {
        return new GameSituationsRepository();
    }

    public interface InteractionListener{
        void onGsNextSessionClicked();
        void onGsPreviousSessionClicked();
    }
}

最后片段的主持人: GameSituationsPresenter.java

public class GameSituationsPresenter extends BasePresenter<GameSituationsContract.View> implements GameSituationsContract.Presenter{
    GameSituationsRepository repo;

    private Bundle viewStateBundle = getStateBundle();

    private static final String TAG = "[" + GameSituationsPresenter.class.getSimpleName() + "] ";

    @Override
    public void onPresenterCreated(){
        Log.d(APP_TAG, TAG + "onPresenterCreated");
        repo = (GameSituationsRepository) getRepo();
        ...
        initializeViews();
    }

    @Override
    public void onPresenterRestored() {
        //So hacky
        initializeViews();
    }

    //NOT CALLED
    @OnLifecycleEvent(value = Lifecycle.Event.ON_START)
    protected void onStart(){
        Log.d(APP_TAG, TAG + "onStart");

        if (isViewAttached()) {
        }
    }

    //NOT CALLED
    @OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
    protected void onStop(){
        if (isViewAttached()) {

        }
    }

    //NOT CALLED
    @OnLifecycleEvent(value = Lifecycle.Event.ON_DESTROY)
    protected void onDestroy() {
        if (isViewAttached()) {
            //Something to do?
        }

        //a little cleanup
        repo = null;
    }

    private void initializeViews(){
        //Do view stuff
    }
}

所以问题是能够接收生命周期事件的片段还是我在实现中遗漏了什么?

提前致谢 .