@Destroy
Since 8.5.2
Syntax
@Destroy
@Destroy(superclass=true)
Description
Target: method, class
Purpose: Marker annotation to identify a destroy method.
Binder calls the method with this annotation when finalizing a ViewModel. In a ViewModel class, only one destroy method is allowed at the most. If you set annotation element superclass to true, the ViewModel's class's destroy method will be invoked first, then the parent's; this logic repeats on super class. If a class has no method with @Destroy
, no method will be called (including the super class's)[1].
For example, in a class hierarchy:
class A {
@Destroy
public void destroyA() {}
}
class B extends A {
@Destroy
public void destroyB() {}
}
class C extends B {
//no @Destroy method
}
class D extends C {
@Destroy(superclass=true)
public void destroyD() {}
}
class E extends D {
@Destroy(superclass=true)
public void destroyE() {}
}
E is the last child class.
When binder finalizes A, it will...
- call A's
@Destroy
methoddestroyA()
- call A's
When binder finalizes B, it will...
- call B's
@Destroy
methoddestroyB()
- A's
@Destroy
method will NOT be called, becausesuperclass=true
was not set in B's@Destroy
- call B's
When binder finalizes C, it will...
- do nothing, because no method was annotated with
@Destroy
- do nothing, because no method was annotated with
When binder finalizes D, it will...
- call D's
@Destroy
methoddestroyD()
- since
superclass=true
, binder will try to look for@Destroy
method in C later - no
@Destroy
method exists in C, so nothing will happen
- call D's
When binder finalizes E, it will...
- call E's
@Destroy
methoddestroyE()
- find
superclass=true
, binder will look for@Destroy
method in D later - call D's
@Destroy
methoddestroyD()
- find
superclass=true
again, binder will look for@Destroy
method in C later - no
@Destroy
method exists in C, so nothing happens
- call E's
We can also use parameter related annotations on destroy method's parameters; please refer to subsections of Syntax/ViewModel/Parameters.
[1]: If you override parent class's destroy method and set superclass=true
, due to Java's limitation, child's method will be called twice. To avoid this, you should remove superclass=true
in child class and use super
to invoke parent's implementation.
class Parent {
@Destroy
public void destroyParent() {}
}
class WrongChild extends Parent {
@Destroy(superclass=true) // binder will try to invoke parent's destroyParent()
@Override
public void destroyParent() {
// but since parent's method was @Override by child
// this method will be called twice
}
}
class CorrectChild extends Parent {
@Destroy // no superclass=true
@Override
public void destroyParent() {
// child implementation of destroyParent()
super.destroyParent(); // manually invoke super class's destroyParent() later
}
}
Example
public class FooViewModel {
@Destroy
public void destroyFoo() {
//finalizing
}
}
public class BarViewModel extends FooViewModel {
@Destroy(superclass=true)
public void destroyBar() {
//destroy method of super class FooViewModel will be called later.
}
}
@Destroy(superclass=true)
public class ChildViewModel extends BarViewModel {
//method body
}