diff --git a/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/annotations/IgnoredWhenDetached.java b/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/annotations/IgnoreWhen.java
similarity index 74%
rename from AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/annotations/IgnoredWhenDetached.java
rename to AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/annotations/IgnoreWhen.java
index 19d7a48774..4519ee5169 100644
--- a/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/annotations/IgnoredWhenDetached.java
+++ b/AndroidAnnotations/androidannotations-core/androidannotations-api/src/main/java/org/androidannotations/annotations/IgnoreWhen.java
@@ -25,7 +25,9 @@
* When used standalone in an {@link EFragment} or in conjunction with the
* {@link UiThread} or {@link Background} annotations, the annotated method will
* be wrapped in an 'if attached' block such that no code will be executed if
- * the {@link EFragment} is no longer bound to its parent activity.
+ * the {@link EFragment} is no longer bound to its parent activity or
+ * DETACHEDthe {@link EFragment} views are destroyed
+ * VIEW_DESTROYED.
*
* Should be used on method that must meet the following criteria
@@ -47,13 +49,13 @@
* ...
*
* @UiThread
- * @IgnoredWhenDetached
+ * @IgnoreWhen(IgnoreWhen.State.DETACHED)
* void killActivity() {
* getActivity().finish();
* }
*
*
- * @IgnoredWhenDetached
+ * @IgnoreWhen(IgnoreWhen.State.VIEW_DESTROYED)
* void updateTitle(String title) {
* getActivity().setTitle(title);
* }
@@ -69,6 +71,29 @@
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
-public @interface IgnoredWhenDetached {
+public @interface IgnoreWhen {
+ /**
+ * The lifecycle state after the method should not be executed.
+ *
+ * @return the state that skips method execution
+ */
+ State value();
+
+ /**
+ * The lifecycle state after the method should not be executed.
+ */
+ enum State {
+
+ /**
+ * Skip execution if the {@link EFragment} is no longer bound to its
+ * parent activity.
+ */
+ DETACHED,
+
+ /**
+ * Skip execution if the {@link EFragment} views are destroyed.
+ */
+ VIEW_DESTROYED
+ }
}
diff --git a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/main/java/org/androidannotations/test/efragment/MyListFragment.java b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/main/java/org/androidannotations/test/efragment/MyListFragment.java
index 4b9ba2d544..fec7653b1c 100644
--- a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/main/java/org/androidannotations/test/efragment/MyListFragment.java
+++ b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/main/java/org/androidannotations/test/efragment/MyListFragment.java
@@ -17,7 +17,7 @@
import org.androidannotations.annotations.Background;
import org.androidannotations.annotations.EFragment;
-import org.androidannotations.annotations.IgnoredWhenDetached;
+import org.androidannotations.annotations.IgnoreWhen;
import org.androidannotations.annotations.ItemClick;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById;
@@ -58,7 +58,7 @@ void uiThread() {
}
@UiThread(propagation = UiThread.Propagation.REUSE)
- @IgnoredWhenDetached
+ @IgnoreWhen(IgnoreWhen.State.DETACHED)
void uiThreadIgnored() {
didExecute = true;
}
@@ -74,16 +74,21 @@ void backgroundThread() {
}
@Background
- @IgnoredWhenDetached
+ @IgnoreWhen(IgnoreWhen.State.DETACHED)
void backgroundThreadIgnored() {
didExecute = true;
}
- @IgnoredWhenDetached
+ @IgnoreWhen(IgnoreWhen.State.DETACHED)
void ignored() {
didExecute = true;
}
+ @IgnoreWhen(IgnoreWhen.State.VIEW_DESTROYED)
+ void ignoreWhenViewDestroyed() {
+ didExecute = true;
+ }
+
void notIgnored() {
didExecute = true;
}
diff --git a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java
index f2a4b512ed..b48ea48ffb 100644
--- a/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java
+++ b/AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/efragment/MyListFragmentTest.java
@@ -122,6 +122,46 @@ public void ignoredWhenDetachedWorksForIgnoredMethod() {
assertFalse(myListFragment.didExecute);
}
+ @Test
+ public void notIgnoredAfterOnCreateView() {
+ assertFalse(myListFragment.didExecute);
+ myListFragment.onCreateView(null, null, null);
+ assertFalse(myListFragment.didExecute);
+ myListFragment.ignoreWhenViewDestroyed();
+ assertTrue(myListFragment.didExecute);
+ }
+
+ @Test
+ public void ignoredWhenViewDestroyedForIgnoredMethod() {
+ assertFalse(myListFragment.didExecute);
+ myListFragment.onDestroyView();
+ myListFragment.ignoreWhenViewDestroyed();
+ assertFalse(myListFragment.didExecute);
+ }
+
+ @Test
+ public void notIgnoredAfterFragmentRecreate() {
+ assertFalse(myListFragment.didExecute);
+ myListFragment.onDestroyView();
+ myListFragment.onCreateView(null, null, null);
+ myListFragment.ignoreWhenViewDestroyed();
+ assertTrue(myListFragment.didExecute);
+ }
+
+ @Test
+ public void notIgnoredBeforeDetached() {
+ assertFalse(myListFragment.didExecute);
+ myListFragment.ignored();
+ assertTrue(myListFragment.didExecute);
+ }
+
+ @Test
+ public void notIgnoredBeforeViewDestroyed() {
+ assertFalse(myListFragment.didExecute);
+ myListFragment.ignoreWhenViewDestroyed();
+ assertTrue(myListFragment.didExecute);
+ }
+
@Test
public void layoutNotInjectedWithoutForce() {
View buttonInInjectedLayout = myListFragment.getView().findViewById(R.id.conventionButton);
diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java
index f5637e9b03..5e2dfa0cd2 100644
--- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java
+++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/holder/EFragmentHolder.java
@@ -15,6 +15,8 @@
*/
package org.androidannotations.holder;
+import static com.helger.jcodemodel.JExpr.FALSE;
+import static com.helger.jcodemodel.JExpr.TRUE;
import static com.helger.jcodemodel.JExpr._new;
import static com.helger.jcodemodel.JExpr._null;
import static com.helger.jcodemodel.JExpr._super;
@@ -23,6 +25,7 @@
import static com.helger.jcodemodel.JMod.PRIVATE;
import static com.helger.jcodemodel.JMod.PUBLIC;
import static com.helger.jcodemodel.JMod.STATIC;
+import static com.helger.jcodemodel.JMod.VOLATILE;
import static org.androidannotations.helper.ModelConstants.generationSuffix;
import javax.lang.model.element.TypeElement;
@@ -46,6 +49,7 @@
public class EFragmentHolder extends EComponentWithViewSupportHolder implements HasInstanceState, HasOptionsMenu, HasOnActivityResult, HasReceiverRegistration, HasPreferences {
private JFieldVar contentView;
+ private JFieldVar viewDestroyedField;
private JBlock setContentViewBlock;
private JVar inflater;
private JVar container;
@@ -208,6 +212,19 @@ private void setContentView() {
contentView = generatedClass.field(PRIVATE, getClasses().VIEW, "contentView" + generationSuffix());
}
+ public JFieldVar getViewDestroyedField() {
+ if (viewDestroyedField == null) {
+ setViewDestroyedField();
+ }
+ return viewDestroyedField;
+ }
+
+ private void setViewDestroyedField() {
+ viewDestroyedField = generatedClass.field(PRIVATE | VOLATILE, getCodeModel().BOOLEAN, "viewDestroyed" + generationSuffix());
+ getSetContentViewBlock().assign(viewDestroyedField, FALSE);
+ getOnDestroyViewAfterSuperBlock().assign(viewDestroyedField, TRUE);
+ }
+
private void setOnCreateView() {
JMethod onCreateView = generatedClass.method(PUBLIC, getClasses().VIEW, "onCreateView");
onCreateView.annotate(Override.class);
diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/core/CorePlugin.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/core/CorePlugin.java
index 1c0e9862ca..a2f868f1cd 100644
--- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/core/CorePlugin.java
+++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/core/CorePlugin.java
@@ -60,7 +60,7 @@
import org.androidannotations.internal.core.handler.HierarchyViewerSupportHandler;
import org.androidannotations.internal.core.handler.HtmlResHandler;
import org.androidannotations.internal.core.handler.HttpsClientHandler;
-import org.androidannotations.internal.core.handler.IgnoredWhenDetachedHandler;
+import org.androidannotations.internal.core.handler.IgnoreWhenHandler;
import org.androidannotations.internal.core.handler.InjectMenuHandler;
import org.androidannotations.internal.core.handler.InstanceStateHandler;
import org.androidannotations.internal.core.handler.ItemClickHandler;
@@ -206,7 +206,7 @@ public List