The easiest way to figure out exactly when injection happens is to inspect the code that AndroidAnnotations generates. For your examples, I made a simple Activity and Fragment as below:
@EActivity(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
@ViewById(R.id.textView)
TextView textView;
@AfterViews
public void activityTestMethod() {
}
}
@EFragment(R.layout.fragment_main)
public class MainFragment extends Fragment {
@ViewById(R.id.imageView)
ImageView imageView;
@AfterViews
public void fragmentTestMethod() {
}
}
and then ran ./gradlew app:assembleDebug
to force AndroidAnnotations to generate the corresponding classes MainActivity_
and MainFragment_
. Let's look at MainActivity_
first (irrelevant code omitted):
public final class MainActivity_
extends MainActivity
implements HasViews, OnViewChangedListener
{
@Override
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
setContentView(R.layout.activity_main);
}
private void init_(Bundle savedInstanceState) {
OnViewChangedNotifier.registerOnViewChangedListener(this);
}
@Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
onViewChangedNotifier_.notifyViewChanged(this);
}
@Override
public void onViewChanged(HasViews hasViews) {
this.textView = hasViews.internalFindViewById(R.id.textView);
activityTestMethod();
}
}
The sequence of events that results in our views being bound and our @AfterViews
methods being called is as follows:
- In
onCreate
, the MainActivity_
instance is registered as an OnViewChangedNotifier
.
onCreate
calls setContentView
.
setContentView
calls notifyViewChanged
, which triggers a (synchronous) call to onViewChanged
.
onViewChanged
binds all fields annotated with @ViewById
, then calls all methods annotated with @AfterViews
.
Therefore, @ViewById
-annotated views are bound and available for use after onCreate
has been called, and @AfterViews
-annotated methods will be executed at the end of onCreate
and before any other Activity lifecycle method.
The story is similar for MainFragment_
:
public final class MainFragment_
extends com.stkent.aatest.MainFragment
implements HasViews, OnViewChangedListener
{
@Override
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
}
private void init_(Bundle savedInstanceState) {
OnViewChangedNotifier.registerOnViewChangedListener(this);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
onViewChangedNotifier_.notifyViewChanged(this);
}
@Override
public void onViewChanged(HasViews hasViews) {
this.imageView = hasViews.internalFindViewById(R.id.imageView);
fragmentTestMethod();
}
}
The sequence of events that results in our views being bound and our @AfterViews
methods being called is as follows:
- In
onCreate
, the MainFragment_
instance is registered as an OnViewChangedNotifier
.
onViewCreated
calls notifyViewChanged
, which triggers a (synchronous) call to onViewChanged
.
onViewChanged
binds all fields annotated with @ViewById
, then calls all methods annotated with @AfterViews
.
Therefore, @ViewById
-annotated views are bound and available for use after onViewCreated
has been called, and @AfterViews
-annotated methods will be executed at the end of onViewCreated
and before any other Fragment lifecycle method.
In both our examples, all view binding is performed in a lifecycle method that occurs much earlier than onResume, so you are safe to access them there :)