Android View related-event distribution mechanism process

After the study of the first two articles, I believe that I have a certain understanding of a process of event distribution (no wonder), then in this chapter, let's take a look at the entire event distribution process from Activity to being consumed. Alright, head out, let's get started.

View structure in Activity

Let's first insert the View structure in the Activity here. In the development process, we usually use setContentView to set the view of the Activity. The visible pages in Android are all attached to the window, that is, the Window, and the DecorView is the top-level view of the Window. In the Android Framework layer, the classes related to window processing are mainly the Window class and its implementation class PhoneWindow, and DecorView is the inner class of PhoneWindow, which inherits FrameLayout.

//PhoneWindow.java
public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
}

The essence of our call to setContentView is to add View to DecorView, you can see the Activity source code:

public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}

Finally, the setContentView of Window is called. We know that the implementation class of Window is PhoneWindow. Let's take a look at the implementation in PhoneWindow:

@Override
public void setContentView(int layoutResID) {
    if (mContentParent == null) {
        installDecor();
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }
    if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,getContext());
        transitionTo(newScene);
    } else {
        mLayoutInflater.inflate(layoutResID, mContentParent);
    }
    mContentParent.requestApplyInsets();
    final Callback cb = getCallback();
    if (cb != null && !isDestroyed()) {
        cb.onContentChanged();
    }
}

You can see that in line 12, the View of the Activity is added to the DecorView (mContentParent is a child View of the DecorView, you can check the generateLayout method of PhoneWindow for details). We can summarize the process of adding a page to a window:

Then we have figured out the process of adding the Activity view to the Window. Of course, this has nothing to do with the content of this chapter.

However, it is still necessary to learn a little more, so let's start today's theme, the general process of event distribution.

Event distribution process

We know that the event distribution initially arrives at the Activity, and then sends it out in sequence, roughly:

Activity ——> PhoneWindow ——> DecorView——> ViewGroup ——> … ——> View

It is such a process. Since we cannot operate PhoneWindow and DecorView, let's analyze the process of Activity, ViewGroup, and View. Let's first analyze the methods of these three related to event distribution:

  • Activity:dispatchTouchEvent()、onTouchEvent()
  • ViewGroup:dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()
  • View:dispatchTouchEvent()、onTouchEvent()

We know that the root View of the management view in Activity is DecorView, let's look at DecorView first:

//DecorView
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    final Callback cb = getCallback();
    return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)
        : super.dispatchTouchEvent(ev);
}
//Window
public final Callback getCallback() {
        return mCallback;
}

DecorView first judges mCallback. If mCallback is not empty, then call the dispatchTouchEvent of mCallback. Let's see how mCallback is assigned:

//Window
public void setCallback(Callback callback) {
    mCallback = callback;
}
//Activity
final void attach(Context context, ActivityThread aThread,
                  Instrumentation instr, IBinder token, int ident,
                  Application application, Intent intent, ActivityInfo info,
                  CharSequence title, Activity parent, String id,
                  NonConfigurationInstances lastNonConfigurationInstances,
                  Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    ...
        mWindow = new PhoneWindow(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    ...
}

From the above code, we can see that the dispathcTouchEvent of DecorView is still the dispathcTouchEvent of Activity, and we know that DecorView is a subclass of FrameLayout, and it is also a ViewGroup. Let's recall the previous ViewGroup and View's event distribution execution process, you can It is easy to draw a process of event distribution of Activity, ViewGroup, and View:

  • View consumption events:

  • ViewGroup consumption events:

  • Activity consumption event:

The whole event distribution process of Activity is like this. This is a typical chain of responsibility pattern in Java. If you understand this design pattern, it will be of great help to understand the Android event distribution mechanism. For the chain of responsibility model, you can refer to the blog post Java model of the chain of responsibility model .

Well, the above is the entire content of this article. If you have any questions about the article or there are errors or omissions in the article, please correct me in the comment area, thank you for watching~

My personal blog , welcome to visit and communicate~

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325647082&siteId=291194637