使用AndroidAnnotations库时,何时注入视图?

时间:2019-04-18 21:29:17

标签: android android-annotations

我想知道何时将@ViewById注释的视图注入AndroidAnnotations。基本上,我想知道在onResume期间访问这些视图之一是否安全?我认为它们是在onCreate期间注入的,但希望确认。

谢谢。

1 个答案:

答案 0 :(得分:3)

准确确定何时发生注入的最简单方法是检查AndroidAnnotations生成的代码。对于您的示例,我做了一个简单的“活动和片段”,如下所示:

@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() {

    }

}

,然后运行./gradlew app:assembleDebug来强制AndroidAnnotations生成相应的类MainActivity_MainFragment_。让我们先来看MainActivity_(忽略不相关的代码):

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();
    }

}

导致绑定我们的视图并调用我们的@AfterViews方法的事件序列如下:

  • onCreate中,MainActivity_实例被注册为OnViewChangedNotifier
  • onCreate呼叫setContentView
  • setContentView调用notifyViewChanged,这会触发对onViewChanged的(同步)调用。
  • onViewChanged绑定所有用@ViewById注释的字段,然后调用所有用@AfterViews注释的方法。

因此,@ViewById注释的视图被绑定,并且在调用onCreate之后可以使用,并且@AfterViews注释的方法将在onCreate的末尾执行。以及其他任何Activity生命周期方法之前。

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();
    }
}

导致绑定我们的视图并调用我们的@AfterViews方法的事件序列如下:

  • onCreate中,MainFragment_实例被注册为OnViewChangedNotifier
  • onViewCreated调用notifyViewChanged,这会触发对onViewChanged的(同步)调用。
  • onViewChanged绑定所有用@ViewById注释的字段,然后调用所有用@AfterViews注释的方法。

因此,@ViewById注释的视图被绑定,并且在调用onViewCreated之后可以使用,并且@AfterViews注释的方法将在onViewCreated的末尾执行。以及其他任何Fragment生命周期方法之前。

在我们的两个示例中,所有视图绑定都是在生命周期方法中执行的,该方法比onResume早得多,因此您可以安全地在其中访问它们:)