androidandroid-annotations

When do views get injected when using the AndroidAnnotations library?


I am wondering when @ViewById-annotated views are injected in AndroidAnnotations. Basically, I want to know if it is safe to access one of these views during onResume? I assume they are injected during onCreate but would like confirmation.

Thank you.


Solution

  • 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:

    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:

    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 :)