Writing in the front
The interview series has reached the ninth issue in a twinkling of an eye. Since the title will be ugly due to the continuous update of the article, the title will be corrected to a similar format as this article.
All right, let’s cut to the chase.
The interview scene
What is the Android event distribution mechanism?
Basically, events are distributed in the order of Activity => ViewGroup => View, and then processed by calling onTouchEvent(). ACTION_DOWN, MotionEvent.ACTION_UP, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_CANCEL
Did you look at the event blocking method in the source code? Or how do you intercept the normal distribution when you’re doing event distribution?
I know of a way to intercept events called… Call, onInterceptEvent ()? Should be, but due to the peacetime project more, really do not have time to pay attention to too much source code.
Well, what do you think, in a list, if you set a click method on both the parent View and the child View, which one will respond first? Why is that?
Must be the first response to the sub-view, as to why, usually know this conclusion, so did not go too in-depth study, but I believe I have a simple look at the source is sure to know.
Start with some bullshit
We may often encounter the above situation, the interviewer wants to know the depth of our knowledge, or is usually learning desire exactly how. Unfortunately, since I conducted mock interviews, 80% of my partners have good development ability, but they do not know the basic questions about similar events. The reason is that, in addition to being busy, most partners still feel that the usual development is also useless, that is, the use of Google will be able to get the correct answer.
This is probably why most people don’t customize their views. Most of the effects are already available on GitHub, and even if they are different, they can be easily modified.
Unfortunately, it’s not for nothing that the extra 20% of people I mock interview always get offers that most people would envy. Perhaps others kept a little more intellectual curiosity in their daily development and learned a lot of vital details.
The body of the
Still can’t digress, in fact such an interview question, is indeed a more common problem, I believe that the same type of article, a search online is everywhere, and a simple look at the attention can know how many people pour in this source type of interview.
In general, the event column is generated from the moment the user presses ACTION_DOWN, and there are three very important event-related methods to mention.
- dispatchTouchEvent()
- onTouchEvent()
- onInterceptTouchEvent()
The event distribution mechanism for an Activity
It is already obvious from the English word that dispatchTouchEvent() is responsible for event distribution. When a click event is generated, the event is first passed to the current Activity, which calls the Activity’s dispatchTouchEvent() method. Let’s take a look at how the source code handles this.
Note in the screenshot that I have added some comments to make it easier to understand that since click events are usually generated as motionEvent.action_down, onUserInteraction() is usually called. Let’s take a look at what’s been done.
Unfortunately, this method implementation is empty, but as you can see from the comments and others, the main function of this method is to implement the screensaver function, and it is triggered when the Activity is at the top of the stack by touching the Home, Back, and Recent keys.
If getWindow().superdispatchTouchEvent (), getWindow() obviously gets Window, and since Window is an abstract class, we can get its subclass PhoneWindow, We see PhoneWindows directly. SuperDispatchTouchEvent () what did the operation.
Direct call a DecorView superDispatchTrackballEvent () method. DecorView descends from FrameLayout as the top-level View, the parent of all interfaces. FrameLayout is a subclass of ViewGroup, so it calls dispatchTouchEvent() directly from the ViewGroup.
The event distribution mechanism of a ViewGroup
We can see this by looking at the dispatchTouchEvent() of the ViewGroup.
Note the code in the red box, as you can see from the comments, that defines a Boolean variable intercept to indicate whether to intercept an event.
OnInterceptTouchEvent (EV) is used to assign value to Intercept. In most cases, onInterceptTouchEvent() returns false, but we can change its return value by overwriting onInterceptTouchEvent(ev). What did we do about the Intercept later?
Ignoring the canceled judgment for the moment, this value also returns false most of the time, so it’s generally acceptable to enter this method when we don’t override onInterceptTouchEvent() to return true.
A For loop iterates through all the subviews of the ViewGroup in reverse order, and then determines one by one whether the click position is in the layout area of the subview, as well as some other things that I won’t go into here For space reasons.
View event distribution mechanism
A ViewGroup is, after all, a View, so we have to keep looking at the dispatchTouchEvent() of the View.
I don’t need to say the first of the three conditions in the red box.
-
(mViewFlags & ENABLED_MASK) == ENABLED This condition is used to determine whether the currently clicked control is enable, but because the basic View is enable, this condition usually returns true.
-
Montouchlistener.ontouch (this, event) is the return value of the method onTouch() that we must override when we call setOnTouchListener().
The onTouch() method takes precedence over the onTouchEvent(event) method.
So onTouchEvent()
As is obvious from the above code, onTouchEvent() will return true to consume the event whenever either the View’s CLICKABLE or LONG_CLICKABLE is true. CLICKABLE and LONG_CLICKABLE indicate that a View can be clicked or long pressed, and we usually use setOnClickListener() and setOnLongClickListener(). The performClick() method is then called in the ACTION_UP event, and let’s see what happens.
As you can see from the screenshot, if mOnClickListener is not empty, its onClick() method is called.
conclusion
I was going to end this, but I’m going to give you a little summary of the review.
1. Android event distribution always follows the Activity => ViewGroup => View delivery order; 2. OnTouch () always executes before onClick()
The Android event distribution mechanism is the most comprehensive and easy to understand mechanism in history, so I directly quote the pictures in it.
-
An event distribution diagram for an Activity
-
ViewGroup Event distribution diagram
-
View event distribution diagram
-
Summary of event distribution workflow
I am the south dust, only do than the heart of the public number, welcome to pay attention to me.