Source code analysis of Android click event distribution mechanism

summary

I've always wanted to write an article about Android event distribution mechanism, but I haven't written it. These two days happen to be the weekend. When I have time, think about writing one. Otherwise, I always stay at the level of being able to use, but I can't understand its internal mechanism. I use the 4.4 source code. It's very complicated to open it. In particular, how events are distributed from activity is too confusing. People who understand the windows message mechanism will find that the event distribution mechanism of Android is very similar to the message distribution mechanism of windows. In fact, this is a typical message "bubbling" mechanism. Many platforms use this mechanism. The message first reaches the bottom view, and then it judges whether it needs it, otherwise it will pass the message to its child view. In this way, The message floats up a little distance from the bubble at the bottom. By analogy, the bubble reaches the top and contacts the air and breaks (the message is processed). Of course, some bubbles float to the top layer and haven't broken (the message is not processed). This message will be processed by the system. For Android, it will be processed by the activity.

Android click event distribution mechanism

1. Pass from activity to underlying view

Click events are represented by motionevent. When a click operation occurs, the event is first delivered to the current activity, and the event is distributed by the activity's dispatchtouchevent. The specific work is completed by the window within the activity. The window will deliver the event to the decor view, which is generally the underlying container of the current interface (that is, the parent container of the view set by setcontentview) can be obtained through activity. GetWindow. Getdecorview(). In addition, when looking at the following code, I mainly look at my comments. Many of the codes are very complex and I can't explain them one by one, but my comments are key points, which are summarized by bloggers after reading the code carefully.

Source code interpretation:

I don't know where the event is passed to the activity, but it doesn't matter. We start from the activity, which is enough for us to understand its internal implementation.

Code:Activity#dispatchTouchEvent

How does window pass events to the ViewGroup

Code:Window#superDispatchTouchEvent

This is actually an abstract function, which also indicates that the application developer should not implement it or call it. What's the situation? Take another look at the description of the following class to the effect that this class can control the appearance and behavior policy of the top-level view, and it also says that the only implementation of this class is located in Android policy. Phonewindow, when you want to instantiate this window class, you don't know its details, because this class will be refactored and only one factory method can be used. Well, it's still very vague. I don't understand, but we can take a look at Android policy. Although this class of phonewindow will be refactored when instantiated, it is only refactored, and its function is similar.

Abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background,title area,default key processing,etc.The only existing implementation of this abstract class is android. policy. PhoneWindow,which you should instantiate when needing a Window. Eventually that class will be refactored and a factory method added for creating Window instances without kNowing about a particular implementation.

Code:PhoneWindow#superDispatchTouchEvent

By the way, the most commonly used window is ((ViewGroup) getwindow(). Getdecorview(). Findviewbyid (Android. R.id.content)) Getchildat (0) is to get the internal view through the activity. This mdecor is obviously getwindow() The view returned by getdecorview (), and the view we set through setcontentview is a child of it. At present, the event is passed to the decorview. Since the decorview inherits from FrameLayout and is our parent view, the final event will be passed to our view. In other words, the event will be passed to our view. Otherwise, how will our application respond to the click event. However, this is not our focus. The focus is on how events should be transmitted after they arrive in our view, which is more useful to us. From here on, the event has been passed to our top-level view. Note: the top-level view is actually the lowest level view, also known as the root view.

2. Event distribution process of the underlying view

After clicking the event to the underlying view (usually a ViewGroup), the dispatchtouchevent method of the ViewGroup will be called. The logic is as follows: if the underlying ViewGroup intercepts the event, that is, onintercepttouchevent returns true, the event will be handled by the ViewGroup. At this time, if the montouchlistener of the ViewGroup is set, ontouch will be called. Otherwise, Ontouchevent will be called, that is, if both are provided, ontouch will mask ontouchevent. In ontouchevent, onclick will be called if monclicklistener is set. If the top-level ViewGroup does not intercept the event, the event will be passed to its child view on the click event chain. At this time, the dispatchtouchevent of the child view will be called. So far, the event has been passed from the bottom-level view to the upper level view. The next behavior is consistent with its bottom-level view. This cycle completes the whole event distribution. In addition, the ViewGroup does not intercept click events by default, and its onintercepttouchevent returns false.

Source code interpretation:

Code:ViewGroup#dispatchTouchEvent

Next, let's look at the ViewGroup's handling of click events

Code:ViewGroup#dispatchTransformedTouchEvent

Look again

Code:View#dispatchTouchEvent

This code is relatively simple. The view handles events in this way: if ontouchlistener is set, ontouch will be called; otherwise, ontouchevent will be called directly, and onclick is triggered by performclick inside ontouchevent. Simply put, if the event is intercepted by the ViewGroup or the ontouchevent of the child view returns false, the event is finally processed by the ViewGroup.

3. Unattended click events

If the ontouchevent of the child view returns false for a click event, the ontouchevent of the parent view will be called directly, and so on. If all views are not processed, they will eventually be processed by the activity. At this time, the ontouchevent of the activity will be called. This problem has been explained in 1 and 2.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>