Created
February 16, 2018 05:50
-
-
Save MFlisar/9d0be636fd5868338d300d400a3367a0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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