Source code analysis of Android event distribution, as an Android Developer

Posted by Bisdale on Wed, 15 Dec 2021 14:20:35 +0100

Activity

There are two main methods related to event delivery in an Activity, dispatchTouchEvent() and onTouchEvent(). Event delivery starts with the dispatchTouchEvent() method of the Activity.

Event distribution

Event distribution method in Activity: dispatchtouchevent (), and its source code is as follows:



//Event distribution

public boolean dispatchTouchEvent(MotionEvent ev) {

    if (ev.getAction() == MotionEvent.ACTION_DOWN) {

        //Empty method

        onUserInteraction();

    }

    if (getWindow().superDispatchTouchEvent(ev)) {

        return true;

    }

    //The onTouchEvent() method returns false by default

    return onTouchEvent(ev);

}



Obviously, only action is processed in the above code_ Down event, description action_ The down event will trigger the event distribution. Then, the superDispatchTouchEvent(ev) method of Window class is called, which is an abstract method. When this method is called, the methods in the specific subclass will be called. The specific subclass of Window class is PhoneWindow class. The specific implementation of superDispatchTouchEvent(ev) method is as follows:

//Abstract methods in Window class

public abstract boolean superDispatchTouchEvent(MotionEvent event);

//Concrete implementation of superDispatchTouchEvent() method in PhoneWindow subclass

@Override  

public boolean superDispatchTouchEvent(MotionEvent event) {  

    return mDecor.superDispatchTouchEvent(event);  

}



Obviously, there is a call to mDecor Superdispatchtouchevent (event), mDecor is a phonewindow Decorview object, which is also the top-level view of the window. It is the root view of a real activity. It inherits FrameLayout through super Dispatchtouchevent will send touchevent to the child views of each activity, that is, we are in activity The view set when setContentView is set in oncreat method. The code reference is as follows:

//DecorView class declaration

private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {

    ...

    public boolean superDispatchTouchEvent(MotionEvent event) {

        //Here, the dispatchTouchEvent method in FrameLayout is called again

        return super.dispatchTouchEvent(event);

    } 

    ...

}



Since the dispatchTouchEvent(event) method is not overridden in FrameLayout, we need the parent class of FrameLayout, that is, the implementation of this method in ViewGroup. This method is used to distribute events. Here, the specific event distribution process needs to be studied.

event processing

The event handling method in Activity: onTouchEvent(), and its source code is as follows:

//Event handling. false is returned by default

public boolean onTouchEvent(MotionEvent event) {

        if (mWindow.shouldCloseOnTouch(this, event)) {

            finish();

            return true;

        }

        //false is returned by default

        return false;

    }



For the onTouchEvent() method, the event is passed to the parent control. Even if false is returned, the event is equivalent to being consumed.

Note: when an Activity distributes events, only return super When dispatchtouchevent (EV), the event continues to pass down. If true or false is returned, the event is consumed, that is, the propagation of the event is terminated.

ViewGroup

There are three main methods related to event delivery in ViewGroup: dispatchTouchEvent(), onInterceptTouchEvent() and onTouchEvent(), as follows:

Event distribution

The event distribution method in ViewGroup: dispatchTouchEvent(), and its source code is as follows:

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

    ...

    //The dispatchTouchEvent() method returns false by default

    boolean handled = false;



    //Determine whether to intercept the distribution of events to the method

    onInterceptTouchEvent(ev);

    ...

    //Cancelled and intercepted are false by default

    if (!canceled && !intercepted) {

        ...

        //This method passes the event to the child View

        dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {

        ...        

    }



    return handled;

}



The function of this method is to traverse the child views in the View Group and hand over the event (ACTION_DOWN) to the child views for processing. It mainly calls oninterceptotouchevent() and dispatchTransformedTouchEvent() methods. Oninterceptotouchevent() returns false by default. The following is the main source code of dispatchTransformedTouchEvent() method:

private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,

            View child, int desiredPointerIdBits){

    ...



    if (child == null) {

        handled = super.dispatchTouchEvent(event);

    } else {

        //Event distribution for child views

        handled = child.dispatchTouchEvent(event);

    }    

    ...

    return handled;

}



Obviously, the dispatchTransformedTouchEvent() method is mainly used to distribute the events of the child View. If there is no child View, the dispatchTouchEvent(event) method of the parent View will be called.

Event interception

The event distribution method onInterceptTouchEvent() in ViewGroup has the following source code:

public boolean onInterceptTouchEvent(MotionEvent ev) {

    ...

    //false is returned by default

    return false;

}



This method returns false by default, which means that event distribution to child views is not intercepted. This method is called in the dispatchTouchEvent() method of View Group.

event processing

The ViewGroup does not have its own onTouchEvent() event handling method. The ViewGroup inherits the View, and its event handling method is the View's event handling method. Its methods are as follows:

public boolean onTouchEvent(MotionEvent event) {

    ...

    //false is returned by default

    return false;

}



This method processes related events. If true is returned, it means that the event is processed. The specific usage will be recorded below.

View

There are two main methods related to event distribution in View: dispatchTouchEvent() and onTouchEvent() methods, as follows:

Topics: Android Design Pattern