OnClickListener.onClick是在View的哪里调用的

OnClickListener.onClick是在View的哪里调用的

我们在View的源码中可以很快的找到performClick()这个方法:

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

那么这个方法是在哪里调用的呢,回想一下,Android的事件机制是先从dispatchTouchEvent()onTouchEvent()的,performClick()onTouchEvent()出现过,我们来看看onTouchEvent()方法部分源码:

if (!focusTaken) {
    if (mPerformClick == null) {
        mPerformClick = new PerformClick();
    }
    if (!post(mPerformClick)) {
        performClick();
    }
}

上面的代码是ViewonTouchEvent()switch语句中UP的一段代码,最关键的是post()这个方法,他的文档写的很清楚,就是将这个PerformClickRunnable对象放入到当前线程的消息队列中。所以我们的performClick()通常是将PerformClick这个Runnable对象放入到消息队列,然后在Looper中取出来调用的。但是会有一种特殊情况是保存到消息队列的时候失败,那么就不处理这个Event了吗,所以在上面的代码中,判断post()的返回值,如果失败,那么就在onTouchEvent()方法中直接调用performClick()方法。

下面是post()方法的文档和源码:

/**
 * 

Causes the Runnable to be added to the message queue. * The runnable will be run on the user interface thread.

* * @param action The Runnable that will be executed. * * @return Returns true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. * * @see #postDelayed * @see #removeCallbacks */ public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); return true; }

但是通过源码可以看出,OnClickListener的onClick是通过消息队列调用的,可是OnTouchListener的onTouch是直接调用的。由于onTouch的代码比较好找,就在dispatchTouchEvent()里面,所以这里就不列出来了。

你可能感兴趣的:(OnClickListener.onClick是在View的哪里调用的)