抱歉,我无法提出更好的问题标题,因为它很难描述......
我正在检查Android的源代码(4.4 KK),特别是View
类,这显示了:
// .... lots of stuff....
AttachInfo mAttachInfo;
// .... lots of stuff....
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
每当我们需要在UI线程上运行时,我们都喜欢使用View.post(Runnable)
。
我在这里不明白的是他们为什么要创建attachInfo
的另一个本地参考?
他们为什么不这样做:
if (mAttachInfo != null) {
return mAttachInfo.mHandler.post(action);
}
除了在方法范围内使attachInfo
不可变以防止错误(甚至认为它们仍然可以意外访问mAttachInfo
)之外,我认为没有任何理由这样做。
另一种可能性是缩短名字,但我认为不值得缩短1个字符。
这是一种设计模式吗?
修改 进一步检查来源显示他们在许多地方使用这种“模式”:
public void postInvalidateOnAnimation() {
// We try only with the AttachInfo because there's no point in invalidating
// if we are not attached to our window
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
}
}
基本上,他们几乎在每个postXXXXXX()
方法中使用它。
EDIT2:
@CommonsWare指出它可能用于以前版本中的匿名内部类,我检查了1.5(Cupcake)~2.3.3(Gingerbread)的来源,这就是post(
)的样子
public boolean post(Runnable action) {
Handler handler;
if (mAttachInfo != null) {
handler = mAttachInfo.mHandler;
} else {
// Assume that post will succeed later
ViewRoot.getRunQueue().post(action);
return true;
}
return handler.post(action);
}
我仍然不明白为什么......
答案 0 :(得分:1)
请记住,可以在UI线程上更新post()
的同时从后台线程调用mAttachInfo
。如果在mAttachInfo
检查之后if (mAttachInfo != null)
检查之前mAttachInfo.mHandler
被设置为空,那么在Android 2.3.3之前使用的代码可能会抛出NPE。
当前代码通过拍摄mAttachInfo
的快照来避免NPE,该快照在方法的生命周期内不会发生变化。
本地变量并不一定是最终的,但是声明它是最终的,这使得它更加明确,它在if (attachInfo != null)
检查后不会变为空。