Skip to content

Instantly share code, notes, and snippets.

@MFlisar
Created February 16, 2018 05:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MFlisar/9d0be636fd5868338d300d400a3367a0 to your computer and use it in GitHub Desktop.
Save MFlisar/9d0be636fd5868338d300d400a3367a0 to your computer and use it in GitHub Desktop.
package com.appindustry.everywherelauncher.mvi;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import com.hannesdorfmann.mosby3.MosbySavedState;
import com.hannesdorfmann.mosby3.MviDelegateCallback;
import com.hannesdorfmann.mosby3.PresenterManager;
import com.hannesdorfmann.mosby3.ViewGroupMviDelegate;
import com.hannesdorfmann.mosby3.ViewGroupMviDelegateCallback;
import com.hannesdorfmann.mosby3.mvi.MviPresenter;
import com.hannesdorfmann.mosby3.mvp.MvpView;
import java.util.UUID;
/**
* Created by flisar on 15.02.2018.
*/
public class MyViewGroupMviDelegateImpl<V extends MvpView, P extends MviPresenter<V, ?>>
implements ViewGroupMviDelegate<V, P>, Application.ActivityLifecycleCallbacks {
// TODO allow custom save state hook in
public static boolean DEBUG = false;
private static final String DEBUG_TAG = "ViewGroupMviDelegateImp";
private ViewGroupMviDelegateCallback<V, P> delegateCallback;
private String mosbyViewId;
private final boolean keepPresenterDuringScreenOrientationChange;
private final boolean isInEditMode;
private P presenter;
private final Context context;
private boolean checkedActivityFinishing = false;
private boolean presenterDetached = false;
private boolean presenterDestroeyed = false;
public MyViewGroupMviDelegateImpl(@NonNull View view,
@NonNull ViewGroupMviDelegateCallback<V, P> delegateCallback,
boolean keepPresenterDuringScreenOrientationChange) {
if (view == null) {
throw new NullPointerException("View is null!");
}
if (delegateCallback == null) {
throw new NullPointerException("MvpDelegateCallback is null!");
}
this.delegateCallback = delegateCallback;
this.keepPresenterDuringScreenOrientationChange = keepPresenterDuringScreenOrientationChange;
this.isInEditMode = view.isInEditMode();
if (!isInEditMode) {
this.context = delegateCallback.getContext();
} else {
this.context = null;
}
}
/**
* Generates the unique (mosby internal) viewState id and calls {@link
* MviDelegateCallback#createPresenter()}
* to create a new presenter instance
*
* @return The new created presenter instance
*/
private P createViewIdAndCreatePresenter() {
P presenter = delegateCallback.createPresenter();
if (presenter == null) {
throw new NullPointerException("Presenter returned from createPresenter() is null.");
}
if (keepPresenterDuringScreenOrientationChange) {
Context context = delegateCallback.getContext();
mosbyViewId = UUID.randomUUID().toString();
PresenterManager.putPresenter(PresenterManager.getActivity(context), mosbyViewId, presenter);
}
return presenter;
}
@NonNull
private Context getContext() {
Context c = delegateCallback.getContext();
if (c == null) {
throw new NullPointerException("Context returned from " + delegateCallback + " is null");
}
return c;
}
@Override
public void onAttachedToWindow() {
if (isInEditMode) return;
boolean viewStateWillBeRestored = false;
if (mosbyViewId == null) {
// No presenter available,
// Activity is starting for the first time (or keepPresenterInstance == false)
presenter = createViewIdAndCreatePresenter();
if (DEBUG) {
Log.d(DEBUG_TAG, "new Presenter instance created: " + presenter);
}
} else {
Context context = getContext();
presenter = null;//PresenterManager.getPresenter(activity, mosbyViewId);
if (presenter == null) {
// Process death,
// hence no presenter with the given viewState id stored, although we have a viewState id
presenter = createViewIdAndCreatePresenter();
if (DEBUG) {
Log.d(DEBUG_TAG,
"No Presenter instance found in cache, although MosbyView ID present. This was caused by process death, therefore new Presenter instance created: "
+ presenter);
}
} else {
viewStateWillBeRestored = true;
if (DEBUG) {
Log.d(DEBUG_TAG, "Presenter instance reused from internal cache: " + presenter);
}
}
}
// presenter is ready, so attach viewState
V view = delegateCallback.getMvpView();
if (view == null) {
throw new NullPointerException(
"MvpView returned from getMvpView() is null. Returned by " + delegateCallback);
}
if (viewStateWillBeRestored) {
delegateCallback.setRestoringViewState(true);
}
presenter.attachView(view);
if (viewStateWillBeRestored) {
delegateCallback.setRestoringViewState(false);
}
if (DEBUG) {
Log.d(DEBUG_TAG,
"MvpView attached to Presenter. MvpView: " + view + " Presenter: " + presenter);
}
}
@Override
public void onDetachedFromWindow() {
if (isInEditMode) return;
detachPresenterIfNotDoneYet();
if (!checkedActivityFinishing) {
boolean destroyPermanently = true;//!ActivityMviDelegateImpl.retainPresenterInstance(
//keepPresenterDuringScreenOrientationChange, activity);
if (destroyPermanently) {
destroyPresenterIfnotDoneYet();
}
// else if (!activity.isFinishing()) {
// // View removed manually from screen
// destroyPresenterIfnotDoneYet();
// }
} // else --> see onActivityDestroyed()
}
/**
* Must be called from {@link View#onSaveInstanceState()}
*/
public Parcelable onSaveInstanceState() {
if (isInEditMode) return null;
Parcelable superState = delegateCallback.superOnSaveInstanceState();
if (keepPresenterDuringScreenOrientationChange) {
return new MosbySavedState(superState, mosbyViewId);
} else {
return superState;
}
}
/**
* Restore the data from SavedState
*
* @param state The state to read data from
*/
private void restoreSavedState(MosbySavedState state) {
mosbyViewId = state.getMosbyViewId();
}
/**
* Must be called from {@link View#onRestoreInstanceState(Parcelable)}
*/
public void onRestoreInstanceState(Parcelable state) {
if (isInEditMode) return;
if (!(state instanceof MosbySavedState)) {
delegateCallback.superOnRestoreInstanceState(state);
return;
}
MosbySavedState savedState = (MosbySavedState) state;
restoreSavedState(savedState);
delegateCallback.superOnRestoreInstanceState(savedState.getSuperState());
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
public void destroy() {
checkedActivityFinishing = true;
boolean destroyedPermanently = true;
if (destroyedPermanently) {
// Whole activity will be destroyed
detachPresenterIfNotDoneYet();
destroyPresenterIfnotDoneYet();
}
}
private void destroyPresenterIfnotDoneYet() {
if (!presenterDestroeyed) {
presenter.destroy();
presenterDestroeyed = true;
if (DEBUG) {
Log.d(DEBUG_TAG, "Presenter destroyed: " + presenter);
}
if (mosbyViewId != null) {
// mosbyViewId == null if keepPresenterDuringScreenOrientationChange == false
//PresenterManager.remove(activity, mosbyViewId);
}
mosbyViewId = null;
}
}
private void detachPresenterIfNotDoneYet() {
if (!presenterDetached) {
presenter.detachView();
presenterDetached = true;
if (DEBUG) {
Log.d(DEBUG_TAG,
"view " + delegateCallback.getMvpView() + " detached from Presenter " + presenter);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment