回調原理: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)。實現了回調。