@Init
Syntax
@Init
@Init(superclass=true)
Description
Target: method, class (since 6.0.1)
Purpose: Marker annotation to identify a initial method.
Binder calls the method with this annotation when initializing a ViewModel. In a ViewModel class, only one initial method is allowed at the most. If you set annotation element superclass to true, the ViewModel's parent class's initial method will be invoked first, then the child's; this logic repeats on super class. If a class has no method with @Init, no method will be called (including the super class's)[1].
For example, in a class hierarchy:
class A {
@Init
public void initA() {}
}
class B extends A {
@Init
public void initB() {}
}
class C extends B {
//no @Init method
}
class D extends C {
@Init(superclass=true)
public void initD() {}
}
class E extends D {
@Init(superclass=true)
public void initE() {}
}
E is the last child class.
When binder initializes A, it will...
- call A's
@Init
methodinitA()
- call A's
When binder initializes B, it will...
- call B's
@Init
methodinitB()
- A's
@Init
method will NOT be called, bacausesuperclass=true
was not set in B's@Init
- call B's
When binder initializes C, it will...
- do nothing, bacause no method was annotated with
@Init
- do nothing, bacause no method was annotated with
When binder initializes D, it will...
- since
superclass=true
, binder will try to look for@Init
method in C first - no
@Init
method exists in C, so nothing will happen - call D's
@Init
methodinitD()
- since
When binder initializes E, it will...
- find
superclass=true
, binder will look for@Init
method in D first - findd
superclass=true
again, binder will look for@Init
method in C first - no
@Init
method exists in C, so nothing happens - call D's
@Init
methodinitD()
- call E's
@Init
methodinitE()
- find
We can also use parameter related annotations on initial method's parameters; please refer to subsections of Syntax/ViewModel/Parameters.
[1]: If you override parent class's initial 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 {
@Init
public void initParent() {}
}
class WrongChild extends Parent {
@Init(superclass=true) // binder will try to invoke parent's initParent()
@Override
public void initParent() {
// but since parent's method was @Override by child
// this method will be called twice
}
}
class CorrectChild extends Parent {
@Init // no superclass=true
@Override
public void initParent() {
super.initParent(); // manually invoke super class's initParent()
// child implementation of initParent()
}
}
Example
public class FooViewModel {
@Init
public void initFoo() {
//initializing
}
}
public class BarViewModel extends FooViewModel {
@Init(superclass=true)
public void initBar() {
//initial method of super class FooViewModel will be called first.
}
}
//since 6.0.1
@Init(superclass=true)
public class ChildViewModel extends BarViewModel {
//method body
}