回调原理:A类调用B类的方法C,B类回调A类的方法D,D方法就是回调的方法。
安卓中的应用:
button.setOnClickListener(new View.OnClickListener() {//注册回调的接口
@Override
public void onClick(View v) {
//执行的逻辑代码
}
});
我们一步一步进行分析
setOnClickListener的源码如下:
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
在这里我们这个匿名内部类作为参数传递过来,该匿名内部类是注册回调的接口。对于getListenerInfo().mOnClickListener = l,把我们传入的 OnClickListener 对象赋值给了 getListenerInfo().mOnClickListener。
接下来我们看 getListenerInfo():
ListenerInfo getListenerInfo() {
if (mListenerInfo != null) {
return mListenerInfo;
}
mListenerInfo = new ListenerInfo();
return mListenerInfo;
}
是个单例,返回的是个ListenerInfo 对象。
接下来我们看ListenerInfo
static class ListenerInfo {
protected OnFocusChangeListener mOnFocusChangeListener;
private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
protected OnScrollChangeListener mOnScrollChangeListener;
private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
public OnClickListener mOnClickListener;
protected OnLongClickListener mOnLongClickListener;
protected OnContextClickListener mOnContextClickListener;
protected OnCreateContextMenuListener mOnCreateContextMenuListener;
private OnKeyListener mOnKeyListener;
private OnTouchListener mOnTouchListener;
private OnHoverListener mOnHoverListener;
private OnGenericMotionListener mOnGenericMotionListener;
private OnDragListener mOnDragListener;
private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
}
这是一个静态内部类,成员包括各种事件的监听接口,其中包含
public OnClickListener mOnClickListener。最终我们传入的 OnClickListener 接口对象参数被mListenerInfo.mOnClickListener 持有了。
最后
public boolean performClick() {
final boolean result;
final ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
result = true;
} else {
result = false;
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
return result;
}
mListenerInfo对象传给了一个静态的 ListenerInfo 对象 li,然后li.mOnClickListener.onClick(this)。实现了回调。