本文仅仅对 AndroidAnnotations 控件如何注入进行源码分析,并不是长篇大论的对整个框架进行分析。主要关注控件初始化,控件销毁。因为深入了解需要花费大量精力,产出却不一定足够大。需要的时候再带着问题去研究,才会收获甚丰,希望对你有帮助。主要学习 AndroidAnnotations 在处理控件初始化和销毁的技巧。如果需要了解注解原理,可参考我的注解系列文章
自定义注解系列文章
- 那些高端、优雅的注解是怎么实现的<0> -- 注解的分类
- 那些高端、优雅的注解是怎么实现的 <1> -- 自定义注解语法
- 那些高端、优雅的注解是怎么实现的<2> -- 解析注解
- 那些高端、优雅的注解是怎么实现的<3> - 可继承性@Inherited
- 那些高端、优雅的注解是怎么实现的<4> -- 使用Annotaion Processing Tool 解析注解
- 那些高端、优雅的注解是怎么实现的<5> --使用Annotaion Processing Tool 自定义注解
- 那些高端、优雅的注解是怎么实现的<6> --自定义持久层框架-类 Hibernate
一:控件初始化及@AfterViews
注解的方法调用
1. 注解后自动生成的类,如 RecordFragment_,如下。
public final class RecordFragment_
extends com.banger.fragment.RecordFragment
implements HasViews, OnViewChangedListener
- 这个类继承了
RecordFragment
,因为RecordFragment
的最上方加入了@EFragment
这个注解。 - 实现了接口
HasViews
中的internalFindViewById
抽象方法,用于初始化控件。该方法具体实现如下,
@Override
public<T extends View> T internalFindViewById(int id) {
return ((T)((contentView_ == null)?null:contentView_.findViewById(id)));
}
- 实现了接口
OnViewChangedListener
中的onViewChanged
抽象方法。在onViewChanged
方法里调用初始化控件方法和@AfterViews
注解的方法。代码如下
@Override
public void onViewChanged(HasViews hasViews) {
this.video_ListView = hasViews.internalFindViewById(R.id.video_ListView);
this.ll_video_save_cancel = hasViews.internalFindViewById(R.id.ll_video_save_cancel);
this.tv_cancel = hasViews.internalFindViewById(R.id.tv_cancel);
this.tv_save_delete = hasViews.internalFindViewById(R.id.tv_save_delete);
if (this.tv_cancel!= null) {
this.tv_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
RecordFragment_.this.tv_cancel();
}
}
);
}
if (this.tv_save_delete!= null) {
this.tv_save_delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
RecordFragment_.this.tv_save_delete();
}
}
);
}
//@AfterViews 注解的方法调用的地方
initView();
}
2.初始化 OnViewChangedNotifier
,代码如下
private final OnViewChangedNotifier onViewChangedNotifier_ = new OnViewChangedNotifier();
private View contentView_;
- 在
RecordFragment_
类的最上方就初始化了OnViewChangedNotifier
-
OnViewChangedNotifier
用于注册view
改变监听器,当view
需要绘制时调用notifyViewChanged 提示监听器进行view
初始化。
3.重写 onCreate 方法,代码如下
@Override
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
}
做了些什么呢?
- 第一行调用
OnViewChangedNotifier
类的静态方法replaceNotifier
。onViewChangedNotifier_
作为参数传入后被赋值给静态变量currentNotifier
,最后该方法返回一个null,存储在变量previousNotifier
中。
public static OnViewChangedNotifier replaceNotifier(OnViewChangedNotifier notifier) {
OnViewChangedNotifier previousNotifier = currentNotifier;
currentNotifier = notifier;
return previousNotifier;
}
- 第二行调用
init_
方法。该方法注册一个 监听view 改变的监听器,参数为this 。部分代码如下
OnViewChangedNotifier.registerOnViewChangedListener(this);
- 再看下registerOnViewChangedListener方法的具体代码实现。
public static void registerOnViewChangedListener(OnViewChangedListener listener) {
if (currentNotifier != null) {
currentNotifier.listeners.add(listener);
}
}
把view 监听器(this)加入到 currentNotifier 的监听器队列中去。currentNotifier
是刚刚在第一行初始化的。
- 第三行调用 super.onCreate(savedInstanceState);就不必多说了吧
- 第四行又再次调用
OnViewChangedNotifier
的静态方法replaceNotifier(previousNotifier)
将OnViewChangedNotifier
中的静态变量currentNotifier
置空。
4. 重写 onViewCreated 方法
- 调用 onViewChangedNotifier_ 的 notifyViewChanged 方法,参数依然是 this 。
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
onViewChangedNotifier_.notifyViewChanged(this);
}
- 再看下 notifyViewChanged 具体代码是怎么实现的
public void notifyViewChanged(HasViews hasViews) {
for (OnViewChangedListener listener : listeners) {
listener.onViewChanged(hasViews);
}
}
- 调用了 listener.onViewChanged 方法。也就是 RecordFragment_ 中的 onViewChanged 方法。因为 RecordFragment_ 实现了 OnViewChangedListener 接口。方法onViewChanged 中又调用了 internalFindViewById 方法(hasViews 接口中的抽象方法由 RecordFragment_实现),从而初始化控件。
- 到这里 RecordFragment 中所有注解的控件都初始化完成了,通过
@AfterViews
注解 定义的方法initView()
也在onViewChanged
方法中调用了。
二:销毁 activity 或 Fragment 时,AndroidAnnotations 会做些什么操作。
1. 重写了 onDestroyView 方法
同样在 RecordFragment_
中,重写了 onDestroyView
方法。如下
@Override
public void onDestroyView() {
super.onDestroyView();
contentView_ = null;
mCrimeRecyclerView = null;
loan_photo_rl2 = null;
loan_type_name_tv = null;
loan_type_name_iv = null;
loan_type_list = null;
loan_op_lv = null;
loan_op_cancle = null;
loan_op_canfirm = null;
loan_photo_rl1 = null;
}
- 可以看到当
Fragment
销毁时AndroidAnnotations
把我们所有的控件都置null
了。这种写法我们在使用Fragment
时也可以作为借鉴。 - 注意
Activity
销毁时并没有做任何其他操作。
总结:
- 在
Activity
的setContentView
或Fragment
的onViewCreated
中初始化各种注解控件和方法(如@click @AfterViews
)
- 在
Fragment
的onDestroyView
方法中把所有注解控件置为null
网友评论