diff --git a/app/build.gradle b/app/build.gradle index 8d0c42c47e..3b36c4c749 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -141,6 +141,9 @@ dependencies { compile "com.pushtorefresh.storio:sqlite-annotations:$STORIO_VERSION" kapt "com.pushtorefresh.storio:sqlite-annotations-processor:$STORIO_VERSION" + // Model View Presenter + compile 'info.android15.nucleus:nucleus:2.0.5' + // Dependency injection compile "com.google.dagger:dagger:$DAGGER_VERSION" kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION" diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.java index ee30033003..ec5a12b5bd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.java @@ -87,9 +87,8 @@ public abstract class BaseRxActivity
extends BaseActivity i } @Override - protected void onDestroy() { - super.onDestroy(); - presenterDelegate.onDropView(); - presenterDelegate.onDestroy(!isChangingConfigurations()); + protected void onPause() { + super.onPause(); + presenterDelegate.onPause(isFinishing()); } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java index e03e6a1cae..84044cdc8c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.base.fragment; import android.os.Bundle; +import android.support.v4.app.Fragment; import eu.kanade.tachiyomi.App; import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter; @@ -84,14 +85,13 @@ public abstract class BaseRxFragment
extends BaseFragment i } @Override - public void onDestroyView() { - super.onDestroyView(); - presenterDelegate.onDropView(); + public void onPause() { + super.onPause(); + presenterDelegate.onPause(getActivity().isFinishing() || isRemoving(this)); } - @Override - public void onDestroy() { - super.onDestroy(); - presenterDelegate.onDestroy(!getActivity().isChangingConfigurations()); + private static boolean isRemoving(Fragment fragment) { + Fragment parent = fragment.getParentFragment(); + return fragment.isRemoving() || (parent != null && isRemoving(parent)); } } diff --git a/app/src/main/java/nucleus/factory/PresenterFactory.java b/app/src/main/java/nucleus/factory/PresenterFactory.java deleted file mode 100644 index 22c0d1a3da..0000000000 --- a/app/src/main/java/nucleus/factory/PresenterFactory.java +++ /dev/null @@ -1,7 +0,0 @@ -package nucleus.factory; - -import nucleus.presenter.Presenter; - -public interface PresenterFactory
{
- P createPresenter();
-}
diff --git a/app/src/main/java/nucleus/factory/PresenterStorage.java b/app/src/main/java/nucleus/factory/PresenterStorage.java
deleted file mode 100644
index 8c36926786..0000000000
--- a/app/src/main/java/nucleus/factory/PresenterStorage.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package nucleus.factory;
-
-import java.util.HashMap;
-
-import nucleus.presenter.Presenter;
-
-/**
- * This is the singleton where all presenters are stored.
- */
-public enum PresenterStorage {
-
- INSTANCE;
-
- private HashMap a type of presenter
- * @return a presenter or null
- */
- public P getPresenter(String id) {
- //noinspection unchecked
- return (P)idToPresenter.get(id);
- }
-
- /**
- * Returns id of a given presenter.
- *
- * @param presenter a presenter to get id for.
- * @return if of the presenter.
- */
- public String getId(Presenter presenter) {
- return presenterToId.get(presenter);
- }
-
- /**
- * Removes all presenters from the storage.
- * Use this method for testing purposes only.
- */
- public void clear() {
- idToPresenter.clear();
- presenterToId.clear();
- }
-}
diff --git a/app/src/main/java/nucleus/factory/ReflectionPresenterFactory.java b/app/src/main/java/nucleus/factory/ReflectionPresenterFactory.java
deleted file mode 100644
index b84d4fd0c2..0000000000
--- a/app/src/main/java/nucleus/factory/ReflectionPresenterFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package nucleus.factory;
-
-import android.support.annotation.Nullable;
-
-import nucleus.presenter.Presenter;
-
-/**
- * This class represents a {@link PresenterFactory} that creates a presenter using {@link Class#newInstance()} method.
- *
- * @param the type of the presenter.
- */
-public class ReflectionPresenterFactory implements PresenterFactory {
-
- private Class presenterClass;
-
- /**
- * This method returns a {@link ReflectionPresenterFactory} instance if a given view class has
- * a {@link RequiresPresenter} annotation, or null otherwise.
- *
- * @param viewClass a class of the view
- * @param a type of the presenter
- * @return a {@link ReflectionPresenterFactory} instance that is supposed to create a presenter from {@link RequiresPresenter} annotation.
- */
- @Nullable
- public static ReflectionPresenterFactory fromViewClass(Class> viewClass) {
- RequiresPresenter annotation = viewClass.getAnnotation(RequiresPresenter.class);
- //noinspection unchecked
- Class presenterClass = annotation == null ? null : (Class )annotation.value();
- return presenterClass == null ? null : new ReflectionPresenterFactory<>(presenterClass);
- }
-
- public ReflectionPresenterFactory(Class presenterClass) {
- this.presenterClass = presenterClass;
- }
-
- @Override
- public P createPresenter() {
- try {
- return presenterClass.newInstance();
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/app/src/main/java/nucleus/factory/RequiresPresenter.java b/app/src/main/java/nucleus/factory/RequiresPresenter.java
deleted file mode 100644
index 081b477019..0000000000
--- a/app/src/main/java/nucleus/factory/RequiresPresenter.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package nucleus.factory;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-import nucleus.presenter.Presenter;
-
-@Inherited
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RequiresPresenter {
- Class extends Presenter> value();
-}
diff --git a/app/src/main/java/nucleus/presenter/Presenter.java b/app/src/main/java/nucleus/presenter/Presenter.java
deleted file mode 100644
index 0c986dfb06..0000000000
--- a/app/src/main/java/nucleus/presenter/Presenter.java
+++ /dev/null
@@ -1,164 +0,0 @@
-package nucleus.presenter;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * This is a base class for all presenters. Subclasses can override
- * {@link #onCreate}, {@link #onDestroy}, {@link #onSave},
- * {@link #onTakeView}, {@link #onDropView}.
- * a type of presenter to return with {@link #getPresenter}.
- */
-public abstract class NucleusActivity extends Activity implements ViewWithPresenter {
-
- private static final String PRESENTER_STATE_KEY = "presenter_state";
-
- private PresenterLifecycleDelegate presenterDelegate =
- new PresenterLifecycleDelegate<>(ReflectionPresenterFactory. fromViewClass(getClass()));
-
- /**
- * Returns a current presenter factory.
- */
- public PresenterFactory getPresenterFactory() {
- return presenterDelegate.getPresenterFactory();
- }
-
- /**
- * Sets a presenter factory.
- * Call this method before onCreate/onFinishInflate to override default {@link ReflectionPresenterFactory} presenter factory.
- * Use this method for presenter dependency injection.
- */
- @Override
- public void setPresenterFactory(PresenterFactory presenterFactory) {
- presenterDelegate.setPresenterFactory(presenterFactory);
- }
-
- /**
- * Returns a current attached presenter.
- * This method is guaranteed to return a non-null value between
- * onResume/onPause and onAttachedToWindow/onDetachedFromWindow calls
- * if the presenter factory returns a non-null value.
- *
- * @return a currently attached presenter or null.
- */
- public P getPresenter() {
- return presenterDelegate.getPresenter();
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (savedInstanceState != null)
- presenterDelegate.onRestoreInstanceState(savedInstanceState.getBundle(PRESENTER_STATE_KEY));
- }
-
- @Override
- protected void onSaveInstanceState(@NonNull Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putBundle(PRESENTER_STATE_KEY, presenterDelegate.onSaveInstanceState());
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- presenterDelegate.onResume(this);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- presenterDelegate.onDropView();
- presenterDelegate.onDestroy(!isChangingConfigurations());
- }
-}
diff --git a/app/src/main/java/nucleus/view/NucleusFragment.java b/app/src/main/java/nucleus/view/NucleusFragment.java
deleted file mode 100644
index 9979a2a8d1..0000000000
--- a/app/src/main/java/nucleus/view/NucleusFragment.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package nucleus.view;
-
-import android.app.Fragment;
-import android.os.Bundle;
-
-import nucleus.factory.PresenterFactory;
-import nucleus.factory.ReflectionPresenterFactory;
-import nucleus.presenter.Presenter;
-
-/**
- * This view is an example of how a view should control it's presenter.
- * You can inherit from this class or copy/paste this class's code to
- * create your own view implementation.
- *
- * @param a type of presenter to return with {@link #getPresenter}.
- */
-public abstract class NucleusFragment extends Fragment implements ViewWithPresenter {
-
- private static final String PRESENTER_STATE_KEY = "presenter_state";
- private PresenterLifecycleDelegate presenterDelegate =
- new PresenterLifecycleDelegate<>(ReflectionPresenterFactory. fromViewClass(getClass()));
-
- /**
- * Returns a current presenter factory.
- */
- public PresenterFactory getPresenterFactory() {
- return presenterDelegate.getPresenterFactory();
- }
-
- /**
- * Sets a presenter factory.
- * Call this method before onCreate/onFinishInflate to override default {@link ReflectionPresenterFactory} presenter factory.
- * Use this method for presenter dependency injection.
- */
- @Override
- public void setPresenterFactory(PresenterFactory presenterFactory) {
- presenterDelegate.setPresenterFactory(presenterFactory);
- }
-
- /**
- * Returns a current attached presenter.
- * This method is guaranteed to return a non-null value between
- * onResume/onPause and onAttachedToWindow/onDetachedFromWindow calls
- * if the presenter factory returns a non-null value.
- *
- * @return a currently attached presenter or null.
- */
- public P getPresenter() {
- return presenterDelegate.getPresenter();
- }
-
- @Override
- public void onCreate(Bundle bundle) {
- super.onCreate(bundle);
- if (bundle != null)
- presenterDelegate.onRestoreInstanceState(bundle.getBundle(PRESENTER_STATE_KEY));
- }
-
- @Override
- public void onSaveInstanceState(Bundle bundle) {
- super.onSaveInstanceState(bundle);
- bundle.putBundle(PRESENTER_STATE_KEY, presenterDelegate.onSaveInstanceState());
- }
-
- @Override
- public void onResume() {
- super.onResume();
- presenterDelegate.onResume(this);
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- presenterDelegate.onDropView();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- presenterDelegate.onDestroy(!getActivity().isChangingConfigurations());
- }
-}
diff --git a/app/src/main/java/nucleus/view/NucleusLayout.java b/app/src/main/java/nucleus/view/NucleusLayout.java
deleted file mode 100644
index 8e9c57f528..0000000000
--- a/app/src/main/java/nucleus/view/NucleusLayout.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package nucleus.view;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import nucleus.factory.PresenterFactory;
-import nucleus.factory.ReflectionPresenterFactory;
-import nucleus.presenter.Presenter;
-
-/**
- * This view is an example of how a view should control it's presenter.
- * You can inherit from this class or copy/paste this class's code to
- * create your own view implementation.
- *
- * @param a type of presenter to return with {@link #getPresenter}.
- */
-public class NucleusLayout extends FrameLayout implements ViewWithPresenter {
-
- private static final String PARENT_STATE_KEY = "parent_state";
- private static final String PRESENTER_STATE_KEY = "presenter_state";
-
- private PresenterLifecycleDelegate presenterDelegate =
- new PresenterLifecycleDelegate<>(ReflectionPresenterFactory. fromViewClass(getClass()));
-
- public NucleusLayout(Context context) {
- super(context);
- }
-
- public NucleusLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public NucleusLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- /**
- * Returns a current presenter factory.
- */
- public PresenterFactory getPresenterFactory() {
- return presenterDelegate.getPresenterFactory();
- }
-
- /**
- * Sets a presenter factory.
- * Call this method before onCreate/onFinishInflate to override default {@link ReflectionPresenterFactory} presenter factory.
- * Use this method for presenter dependency injection.
- */
- @Override
- public void setPresenterFactory(PresenterFactory presenterFactory) {
- presenterDelegate.setPresenterFactory(presenterFactory);
- }
-
- /**
- * Returns a current attached presenter.
- * This method is guaranteed to return a non-null value between
- * onResume/onPause and onAttachedToWindow/onDetachedFromWindow calls
- * if the presenter factory returns a non-null value.
- *
- * @return a currently attached presenter or null.
- */
- public P getPresenter() {
- return presenterDelegate.getPresenter();
- }
-
- /**
- * Returns the unwrapped activity of the view or throws an exception.
- *
- * @return an unwrapped activity
- */
- public Activity getActivity() {
- Context context = getContext();
- while (!(context instanceof Activity) && context instanceof ContextWrapper)
- context = ((ContextWrapper) context).getBaseContext();
- if (!(context instanceof Activity))
- throw new IllegalStateException("Expected an activity context, got " + context.getClass().getSimpleName());
- return (Activity) context;
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- Bundle bundle = new Bundle();
- bundle.putBundle(PRESENTER_STATE_KEY, presenterDelegate.onSaveInstanceState());
- bundle.putParcelable(PARENT_STATE_KEY, super.onSaveInstanceState());
- return bundle;
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- Bundle bundle = (Bundle) state;
- super.onRestoreInstanceState(bundle.getParcelable(PARENT_STATE_KEY));
- presenterDelegate.onRestoreInstanceState(bundle.getBundle(PRESENTER_STATE_KEY));
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (!isInEditMode())
- presenterDelegate.onResume(this);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- presenterDelegate.onDropView();
- presenterDelegate.onDestroy(!getActivity().isChangingConfigurations());
- }
-}
diff --git a/app/src/main/java/nucleus/view/ParcelFn.java b/app/src/main/java/nucleus/view/ParcelFn.java
deleted file mode 100644
index 5b4fedca78..0000000000
--- a/app/src/main/java/nucleus/view/ParcelFn.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package nucleus.view;
-
-import android.os.Parcel;
-
-class ParcelFn {
-
- private static final ClassLoader CLASS_LOADER = ParcelFn.class.getClassLoader();
-
- static a type of the presenter.
- */
-public final class PresenterLifecycleDelegate {
-
- private static final String PRESENTER_KEY = "presenter";
- private static final String PRESENTER_ID_KEY = "presenter_id";
-
- @Nullable private PresenterFactory presenterFactory;
- @Nullable private P presenter;
- @Nullable private Bundle bundle;
-
- private boolean presenterHasView;
-
- public PresenterLifecycleDelegate(@Nullable PresenterFactory presenterFactory) {
- this.presenterFactory = presenterFactory;
- }
-
- /**
- * {@link ViewWithPresenter#getPresenterFactory()}
- */
- @Nullable
- public PresenterFactory getPresenterFactory() {
- return presenterFactory;
- }
-
- /**
- * {@link ViewWithPresenter#setPresenterFactory(PresenterFactory)}
- */
- public void setPresenterFactory(@Nullable PresenterFactory presenterFactory) {
- if (presenter != null)
- throw new IllegalArgumentException("setPresenterFactory() should be called before onResume()");
- this.presenterFactory = presenterFactory;
- }
-
- /**
- * {@link ViewWithPresenter#getPresenter()}
- */
- public P getPresenter() {
- if (presenterFactory != null) {
- if (presenter == null && bundle != null)
- presenter = PresenterStorage.INSTANCE.getPresenter(bundle.getString(PRESENTER_ID_KEY));
-
- if (presenter == null) {
- presenter = presenterFactory.createPresenter();
- PresenterStorage.INSTANCE.add(presenter);
- presenter.create(bundle == null ? null : bundle.getBundle(PRESENTER_KEY));
- }
- bundle = null;
- }
- return presenter;
- }
-
- /**
- * {@link android.app.Activity#onSaveInstanceState(Bundle)}, {@link android.app.Fragment#onSaveInstanceState(Bundle)}, {@link android.view.View#onSaveInstanceState()}.
- */
- public Bundle onSaveInstanceState() {
- Bundle bundle = new Bundle();
- getPresenter();
- if (presenter != null) {
- Bundle presenterBundle = new Bundle();
- presenter.save(presenterBundle);
- bundle.putBundle(PRESENTER_KEY, presenterBundle);
- bundle.putString(PRESENTER_ID_KEY, PresenterStorage.INSTANCE.getId(presenter));
- }
- return bundle;
- }
-
- /**
- * {@link android.app.Activity#onCreate(Bundle)}, {@link android.app.Fragment#onCreate(Bundle)}, {@link android.view.View#onRestoreInstanceState(Parcelable)}.
- */
- public void onRestoreInstanceState(Bundle presenterState) {
- if (presenter != null)
- throw new IllegalArgumentException("onRestoreInstanceState() should be called before onResume()");
- this.bundle = ParcelFn.unmarshall(ParcelFn.marshall(presenterState));
- }
-
- /**
- * {@link android.app.Activity#onResume()},
- * {@link android.app.Fragment#onResume()},
- * {@link android.view.View#onAttachedToWindow()}
- */
- public void onResume(Object view) {
- getPresenter();
- if (presenter != null && !presenterHasView) {
- //noinspection unchecked
- presenter.takeView(view);
- presenterHasView = true;
- }
- }
-
- /**
- * {@link android.app.Activity#onDestroy()},
- * {@link android.app.Fragment#onDestroyView()},
- * {@link android.view.View#onDetachedFromWindow()}
- */
- public void onDropView() {
- if (presenter != null && presenterHasView) {
- presenter.dropView();
- presenterHasView = false;
- }
- }
-
- /**
- * {@link android.app.Activity#onDestroy()},
- * {@link android.app.Fragment#onDestroy()},
- * {@link android.view.View#onDetachedFromWindow()}
- */
- public void onDestroy(boolean isFinal) {
- if (presenter != null && isFinal) {
- presenter.destroy();
- presenter = null;
- }
- }
-}
diff --git a/app/src/main/java/nucleus/view/ViewWithPresenter.java b/app/src/main/java/nucleus/view/ViewWithPresenter.java
deleted file mode 100644
index 979065a5a4..0000000000
--- a/app/src/main/java/nucleus/view/ViewWithPresenter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package nucleus.view;
-
-import nucleus.factory.PresenterFactory;
-import nucleus.factory.ReflectionPresenterFactory;
-import nucleus.presenter.Presenter;
-
-public interface ViewWithPresenter {
-
- /**
- * Returns a current presenter factory.
- */
- PresenterFactory getPresenterFactory();
-
- /**
- * Sets a presenter factory.
- * Call this method before onCreate/onFinishInflate to override default {@link ReflectionPresenterFactory} presenter factory.
- * Use this method for presenter dependency injection.
- */
- void setPresenterFactory(PresenterFactory presenterFactory);
-
- /**
- * Returns a current attached presenter.
- * This method is guaranteed to return a non-null value between
- * onResume/onPause and onAttachedToWindow/onDetachedFromWindow calls
- * if the presenter factory returns a non-null value.
- *
- * @return a currently attached presenter or null.
- */
- P getPresenter();
-}