Thoughts from a chat: Android event distribution mechanism, android Distribution

Source: Internet
Author: User

Thoughts from a chat: Android event distribution mechanism, android Distribution

Reprinted please declare: http://www.cnblogs.com/courtier/p/4295235.html

  • Origin:

One day I saw the following piece of information (such as). I thought about it (of course not the question this person asked): "Why can the Activity interact with the interface and why?

Events can be passed ?" With these questions, I checked some materials and information on the Internet and obtained the following principles.

My summary: As we all know, Activity is not a real Display object. The Activity class has a member variable called: The mWindow type is Window, and this is

We will display the type of the form-Phone Window (created by PolicyManager. makeNewWindow ). The PhoneWindow class has two important member variables.

MDecor and mContentParent. Here, mDecor (internal class) is the main class, and the View we add to mContentParent is placed here. For example:

The instance that holds the Phone Window (mDecor ). Each ViewRoot object has a member variable of the WindowManager. LayoutParams type.

M1_wattributes, which points to a ViewGroup. LayoutParams object to describe an Activity component corresponding to this ViewRoot object.

UI layout information. So when will ViewRoot know the change? It mainly depends on WindowManagerService (responsible for event processing ).

Let's take a look at the figure. (IWindowSession is the variable of ViewRoot)

(Wms-> viewroot-> phonewindow. DecorView-> Activity-> phonewindow. DecorView-> ViewGroup)

  • Start from ViewGroup to understand the source code:
Public class FrameLayout extends ViewGroup {//... // Check for interception. final boolean intercepted; if (actionMasked = MotionEvent. ACTION_DOWN | mFirstTouchTarget! = Null) {// disallowIntercept: indicates that if the child control requests the parent control, the event is not blocked. // Call requestDisallowInterceptTouchEvent final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT )! = 0; if (! DisallowIntercept) {intercepted = onInterceptTouchEvent (ev); ev. setAction (action); // restore action in case it was changed} else {intercepted = false ;}} else {// There are no touch targets and this action is not an initial down // so this view group continues to intercept touches. intercepted = true ;}//.. // if it is intercepted, It is MotionEvent. ACTION_CANCEL final boolean canceled = resetCancelNextUpFlag (th Is) | actionMasked = MotionEvent. ACTION_CANCEL; // process ActionDown if (! Canceled &&! Intercepted) {if (actionMasked = MotionEvent. ACTION_DOWN | (split & actionMasked = MotionEvent. ACTION_POINTER_DOWN) | actionMasked = MotionEvent. ACTION_HOVER_MOVE) {final int actionIndex = ev. getActionIndex (); // always 0 for down final int idBitsToAssign = split? 1 <ev. getPointerId (actionIndex): TouchTarget. ALL_POINTER_IDS; // Clean up earlier touch targets for this pointer id in case they // have become out of sync. removePointersFromTouchTargets (idBitsToAssign); final int childrenCount = mChildrenCount; if (newTouchTarget = null & childrenCount! = 0) {final float x = ev. getX (actionIndex); final float y = ev. getY (actionIndex); // Find a child that can receive the event. // Scan children from front to back. final View [] children = mChildren; final boolean customOrder = isChildrenDrawingOrderEnabled (); for (int I = childrenCount-1; I> = 0; I --) {final int childIndex = customOrder? GetChildDrawingOrder (childrenCount, I): I; final View child = children [childIndex]; if (! CanViewReceivePointerEvents (child) |! IsTransformedTouchPointInView (x, y, child, null) {continue;} newTouchTarget = getTouchTarget (child); if (newTouchTarget! = Null) {// Child is already refreshing ing touch within its bounds. // subevent received, Jump Out // Give it the new pointer in addition to the ones it is handling. newTouchTarget. pointerIdBits | = idBitsToAssign; break;} response (child); if (dispatchTransformedTouchEvent (ev, false, child, idBitsToAssign) {// Child wants to receive touch within its bounds. mLastTouchDownTime = ev. getDownTime (); mLastTouc HDownIndex = childIndex; mLastTouchDownX = ev. getX (); mLastTouchDownY = ev. getY (); newTouchTarget = addTouchTarget (child, idBitsToAssign); alreadyDispatchedToNewTouchTarget = true; break ;}} if (newTouchTarget = null & mFirstTouchTarget! = Null) {// Did not find a child to receive the event. // Assign the pointer to the least recently added target. newTouchTarget = mFirstTouchTarget; while (newTouchTarget. next! = Null) {newTouchTarget = newTouchTarget. next;} newTouchTarget. pointerIdBits | = idBitsToAssign ;}}// Dispatch to touch targets. // The condition that the method executed above will not be executed is: // 1: Your action is not ActionDown // 2: The interception event has been started if (mFirstTouchTarget = null) {// mFirstTouchTarget = null: there are only two cases: // first: interception on the top; // Second: The OnTouch event is not consumed (that is, the subclass is unable to consume the parent class) that is to say, after the ACTION_DOWN event is processed, No way to handle the event is found to return // No touch targets so treat this as an ordinary view. // dispatchTr AnsformedTouchEvent: Call the parent class handled = dispatchTransformedTouchEvent (ev, canceled, null, TouchTarget. ALL_POINTER_IDS);} else {// Dispatch to touch targets, excluding the new touch target if we already // dispatched to it. cancel touch targets if necessary. touchTarget predecessor = null; TouchTarget target = mFirstTouchTarget; while (target! = Null) {final TouchTarget next = target. next; if (alreadyDispatchedToNewTouchTarget & target = newTouchTarget) {handled = true;} else {final boolean cancelChild = resetCancelNextUpFlag (target. child) | intercepted; if (dispatchTransformedTouchEvent (ev, cancelChild, target. child, target. pointerIdBits) {handled = true;} if (cancelChild) {if (predecessor = null) {mFirstTouchTarget = next;} else {predecessor. next = next;} target. recycle (); target = next; continue ;}} predecessor = target; target = next ;}}//.... viewGrouo ended}
  • View to understand the source code: (various views under ViewGroup)
Public boolean dispatchTouchEvent (MotionEvent event) {if (mInputEventConsistencyVerifier! = Null) {mInputEventConsistencyVerifier. onTouchEvent (event, 0);} if (onFilterTouchEventForSecurity (event) {// noinspection SimplifiableIfStatement ListenerInfo li = mListenerInfo; // li. mOnTouchListener. onTouch: The OnTouchListener that we call frequently. Return Value: // True: the onTouchEvent will not be executed. The Onclicklistener method will be executed. // False: The Onclicklistener if (li! = Null & li. mOnTouchListener! = Null & (mViewFlags & ENABLED_MASK) = ENABLED & li. mOnTouchListener. onTouch (this, event) {return true;} if (onTouchEvent (event) {return true ;}} if (mInputEventConsistencyVerifier! = Null) {mInputEventConsistencyVerifier. onUnhandledEvent (event, 0);} return false ;}
  • Summary:

1: about interception events:

Question 1: Why is there an interception event (think about it as follows): I think there is a conflict between the two events (Parent and Child views) and there is a question about which system execution is performed. Blocks sub-classes.

The interception event has several important points: 1. After being intercepted, the Child control receives ACTION_CANCEL. 2: the parent class intercepts permanent interception at a time.

2: OnTouchListener and OnClickListener:

Question 2: Why can't I execute the following statement after OnTouchListener returns true? I think it is because two events are overlapped. Touch event: already

Including (the nature of Click ).

3: I would like to express my gratitude for referring to the articles by many experts (more than a dozen articles), so that I can learn more easily. If I have any mistakes, please leave a message. Thank you.Happy New Year!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.