1. 程式人生 > >Activity dispatchTouchEvent事件分發--總結(一)

Activity dispatchTouchEvent事件分發--總結(一)

先看一下除錯的堆疊資訊

MainActivity的dispatchTouchEvent的方法定義如下

@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		return super.dispatchTouchEvent(event);
	}

從堆疊資訊可以看出呼叫MainActivity的地方在

PhoneWindow$DecorView.dispatchTouchEvent(MotionEvent) line: 1918

檢視原始碼 其中Callback 、DecorView都是Window的一個內部類

public abstract class Window {  

 /**
     * Set the Callback interface for this window, used to intercept key
     * events and other dynamic operations in the window.
     *
     * @param callback The desired Callback interface.
     */
    public void setCallback(Callback callback) {
        mCallback = callback;
    }


    /**
     * Return the current Callback interface for this window.
     */
    public final Callback getCallback() {
        return mCallback;
    }

 /**
     * API from a Window back to its caller.  This allows the client to
     * intercept key dispatching, panels and menus, etc.
     */
    public interface Callback {
<span style="white-space:pre">	</span>。。。。。。//方法略
      }

     private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {

 <span style="white-space:pre">	</span>@Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            final Callback cb = getCallback();
            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)
                    : super.dispatchTouchEvent(ev);
        }

}

DecorView.dispatchTouchEvent 方法 cb.dispatchTouchEvent 正式呼叫MainActivity的地方

可以檢視一下android.app.Activity 的定義 implement Window.Callback

執行到Activity#dispatchTouchEvent的時候

/**
     * Called to process touch screen events.  You can override this to
     * intercept all touch screen events before they are dispatched to the
     * window.  Be sure to call this implementation for touch screen events
     * that should be handled normally.
     * 
     * @param ev The touch screen event.
     * 
     * @return boolean Return true if this event was consumed.
     */
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

看了一下getWindow().superDispatchTouchEvent

window中的定義如下

    @Override
    public boolean superDispatchTouchEvent(MotionEvent event) {
        return mDecor.superDispatchTouchEvent(event);
    }

DocorView的定義如下
 public boolean superDispatchTouchEvent(MotionEvent event) {
            return super.dispatchTouchEvent(event);
        }
因為DocorView繼承了FrameLayout
  private final class DecorView extends FrameLayout implements RootViewSurfaceTaker
FrameLayout繼承了ViewGroup
public class FrameLayout extends ViewGroup {
/**
     * {@inheritDoc}
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        。。
    }

剩下的工作就是研讀 GroupView的dispatchTouchEvent方法了

其中Activity#dispatchTouchEvent方法

getWindow().superDispatchTouchEvent(ev) 如果 == true 則直接return 

即 Activity的 onTouchEvent就將不會執行