The underlying principle of Windows add view in Android

Source: Internet
Author: User

One, window and WindowManagerwindow is an abstract class, its implementation is Phonewindow, creating a window is very simple, only need to create a windowmanager, window specifically implemented in Windowmanagerservice, The interaction between WindowManager and Windowmanagerservice is an IPC process.
Here's an example of using WindowManager:
Mfloatingbutton = new Button (this);            Mfloatingbutton.settext ("window");            Mlayoutparams = new Windowmanager.layoutparams (                    layoutparams. Wrap_content, layoutparams.wrap_content, 0, 0,                    PixelFormat. TRANSPARENT);            Mlayoutparams. Flags = Layoutparams.flag_not_touch_modal                    | Layoutparams. Flag_not_focusable                    | Layoutparams. flag_show_when_locked;            Mlayoutparams. Type = Layoutparams. Type_system_error;            Mlayoutparams. Gravity = Gravity. Left | Gravity. TOP;            Mlayoutparams. x = +;            Mlayoutparams. y = +;            Mfloatingbutton.setontouchlistener (this);             

flags and type two properties are important, some properties are described below, first, flags:Flag_not_touch_modalIndicates that there is no need to get the focus, nor does it need to receive various inputs, and the final event is passed directly to the lower window with focus.flag_not_focusable:In the area outside this window, click events to pass to the underlying window. The current area is handled by itself, this is generally set, very important. flag_show_when_locked : Open to allow window to appear on the lock screen. Look again at the type parameter: There are three types of window: Application window, sub window, System window. The application class corresponds to an activity, and the child window cannot exist alone, and it needs to be attached to the parent window, such as a commonly used dialog. The System window is a window that needs to be declared and created again, such as toast. Window has the z-ordered attribute, the larger the level, the more the top layer. application window level 1-99, sub window1000-1999, System 2000-2999. This level corresponds to the type parameter of the WindowManager. There are two type_system_overlay or type_system_error commonly used at the system level. For example, to use Type_system_error, just mlayoutparams.type = Layoutparams.type_system_error. Also add permissions <uses-permission andorid:name= "Android.permission.SYSTEM_ALERT_WINDOW"/>. With a basic understanding of window, let's look at how the bottom layer implements the load view.Two,creation of window. in fact, the creation of window and I wrote a blog layoutinflater source analysis a bit similar. creation of window is in the Attach method created by activity, through the Policymanager Makenewwindow method. The callback interface of window is implemented in activity, so the activity method is recalled when the window state changes. such as Onattachedtowindow and so on. the real implementation class of Policymanager is policy, look at its code:
Public Window Makenewwindow (context context) {        return new Phonewindow (context);    }
To this window to create the complete. The following is an analysis of how view is attached to a window. Look at the Setcontentview method of activity.
public void Setcontentview (int layoutresid) {        GetWindow (). Setcontentview (LAYOUTRESID);        Initwindowdecoractionbar ();    }
Two parts, setting the content and setting the Actionbar.the concrete implementation of window is Phonewindow, look at its setcontent.
public void Setcontentview (int layoutresid) {//Note:feature_content_transitions May is set in the process of installing the Window//decor, when theme attributes and the like is crystalized.        Do not check the feature//before this happens.        if (mcontentparent = = null) {Installdecor ();        } else if (!hasfeature (feature_content_transitions)) {mcontentparent.removeallviews (); } if (Hasfeature (feature_content_transitions)) {final Scene newscene = Scene.getsceneforlayout (mcontent            Parent, Layoutresid, GetContext ());        Transitionto (Newscene);        } else {mlayoutinflater.inflate (layoutresid, mcontentparent);        } final Callback cb = Getcallback ();        if (CB! = null &&!isdestroyed ()) {cb.oncontentchanged (); }   } 
See it, analyze it again. This is done in three steps: 1. If there is no Decorview, the Decorview is created in Generatedecor () in Installdecor. Analyzed before, this time no longer analyze it. 2. Add the view to the mcontentparent in Decorview. 3. Callback the Oncontentchanged interface of the activity.after doing this, Decorview was created, but not formally added to the window. In Activityresumeactivity, the activity's onresume is called first, and then the makevisible,makevisible in the activity is called to actually add the view, the code is as follows:
  void Makevisible () {        if (!mwindowadded) {            Viewmanager wm = Getwindowmanager ();            Wm.addview (Mdecor, GetWindow (). GetAttributes ());            mwindowadded = true;        }        Mdecor.setvisibility (view.visible);    }
Through the abovethe AddView method adds a view to the window. Third, window operation view internal mechanism1.window Add a window corresponding to a view and a viewrootimpl,window and view through the Viewrootimpl to establish a connection, it does not exist, the entity is a view. It can only be manipulated by WindowManager. The WindowManager implementation class is Windowmanagerimpl. It does not directly implement the three major operations, but is entrusted to Windowmanagerglobal. The implementation of AddView is divided into the following steps:1. Check that the parameters are valid.
if (view = = null) {throw new IllegalArgumentException ("View must not is null");        } if (display = = null) {throw new IllegalArgumentException ("Display must not is null"); } if (! ( params instanceof Windowmanager.layoutparams) {throw new IllegalArgumentException ("params must be Windowmanag Er.        Layoutparams ");        } final Windowmanager.layoutparams wparams = (windowmanager.layoutparams) params;        if (ParentWindow! = null) {Parentwindow.adjustlayoutparamsforsubwindow (wparams); } else {//If there ' s no parent and we ' re running on L or above (or in the/system context), ASSU            Me we want hardware acceleration.            Final context context = View.getcontext (); if (context! = null && context.getapplicationinfo (). targetsdkversion >= Build.version_codes. LOLLIPOP) {wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_Accelerated; }        }

2. Create the Viewrootimpl and add the view to the list.
root = new Viewrootimpl (View.getcontext (), display);            View.setlayoutparams (wparams);            Mviews.add (view);            Mroots.add (root);            Mparams.add (Wparams);
3.update the interface with Viewrootimpl and complete the window add process.
Root.setview (view, Wparams, Panelparentview);
the above root is the Viewrootimpl,setview in the Requestlayout () to complete the asynchronous refresh, to see the requestlayout:
public void Requestlayout () {        if (!mhandlinglayoutinlayoutrequest) {            checkthread ();            Mlayoutrequested = true;            Scheduletraversals ();        }    }
next through the Windowsession to complete the window add process, Windowsession is a binder object, the real implementation class is Session,window add is an IPC call.
 try {                    Morigwindowtype = Mwindowattributes.type;                    Mattachinfo.mrecomputeglobalattributes = true;                    Collectviewattributes (); res = Mwindowsession.addtodisplay (Mwindow, MSeq, Mwindowattributes, Gethostvisibility (), MDISPL                Ay.getdisplayid (), Mattachinfo.mcontentinsets, Mattachinfo.mstableinsets, Minputchannel);                    } catch (RemoteException e) {madded = false;                    MView = null;                    Mattachinfo.mrootview = null;                    Minputchannel = null;                    Mfallbackeventhandler.setview (NULL);                    Unscheduletraversals ();                    Setaccessibilityfocus (null, NULL); throw new RuntimeException ("Adding window Failed", e);} 
The window is added via Windowmanagerservice within the session.
  public int addtodisplay (iwindow window, int seq, windowmanager.layoutparams attrs,            int viewvisibility, int Displayid , rect outcontentinsets, rect outstableinsets,            inputchannel outinputchannel) {        return Mservice.addwindow (this , window, seq, Attrs, viewvisibility, Displayid,                outcontentinsets, Outstableinsets, Outinputchannel);    }
Within the Windowmanagerservice, a separate session is reserved for each application.
Removal of 2.windowlook at the Removeview of Windowmanagerglobal:
public void Removeview (View view, Boolean immediate) {        if (view = = null) {            throw new IllegalArgumentException ("Vie W must not is null ");        }        Synchronized (mLock) {            int index = findviewlocked (view, true);            View Curview = mroots.get (index). GetView ();            Removeviewlocked (index, immediate);            if (Curview = = view) {                return;            }            throw new IllegalStateException ("Calling with View" + View                    + "but the Viewancestor are attached to" + Curview); 
   }    }

First Call findviewlocked to find the index of the delete view, which is the process of establishing an array traversal. Then call removeviewlocked again to do a further removal.
private void removeviewlocked (int index, Boolean immediate) {        Viewrootimpl root = Mroots.get (index);        View view = Root.getview ();        if (view = null) {            Inputmethodmanager IMM = Inputmethodmanager.getinstance ();            if (IMM! = null) {                imm.windowdismissed (mviews.get (index). Getwindowtoken ());}        }        Boolean deferred = Root.die (immediate);        if (view! = null) {            view.assignparent (null);            if (deferred) {                mdyingviews.add (view);}}    }
The actual delete operation is Viewrootimpl to complete. The WindowManager provides two kinds of removal interfaces, Removeviewimmediate,removeview. They represent asynchronous deletes and synchronous deletions, respectively. The specific delete operation is done by Viewrootimpl die.
Boolean Die (Boolean immediate) {        //Make sure we do execute immediately if we is in the middle of a traversal or the Damage        //done by Dispatchdetachedfromwindow would cause havoc on return.        if (immediate &&!misintraversal) {            Dodie ();            return false;        }        if (!misdrawing) {            destroyhardwarerenderer ();        } else {            log.e (TAG, "attempting to destroy the window while DRA wing!\n "+                    "  window= "+ This +", title= "+ mwindowattributes.gettitle ());        }        Mhandler.sendemptymessage (Msg_die);        return true;    }
if it is removeviewimmediate, call Dodie immediately, if it is Removeview, send a message with handler, Viewrootimpl in handler will process the message and call Dodie. Focus on the Dodie:
void Dodie () {checkthread ();        if (LOCAL_LOGV) log.v (TAG, "die on" + This + "of" + msurface);            Synchronized (this) {if (mremoved) {return;            } mremoved = true;            if (madded) {Dispatchdetachedfromwindow ();                } if (madded &&!mfirst) {destroyhardwarerenderer ();                    if (MView! = null) {int viewvisibility = mview.getvisibility ();                    Boolean viewvisibilitychanged = mviewvisibility! = viewvisibility; if (mwindowattributeschanged | | viewvisibilitychanged) {//If layout params has been changed, fir St give them//to the window manager for sure it has the correct//ANI                        mation info.                       try {if (Relayoutwindow (Mwindowattributes, viewvisibility, False)             & windowmanagerglobal.relayout_res_first_time)! = 0) {Mwindowsession.fini                            Shdrawing (Mwindow); }} catch (RemoteException e) {}} MS                Urface.release ();        }} madded = false;    } windowmanagerglobal.getinstance (). Doremoveview (this); }
There are four main things to do: 1. Garbage collection related work, such as clear data, callback, etc. 2. Delete window through the Remove method of session, and finally call Windowmanagerservice's Removewindow
3. Call Dispathdetachedfromwindow, internally calling Ondetachedfromwindow () and ondetachedfromwindowinternal (). When view is removed, it calls Ondetachedfromwindow, which is used for some resource recycling. 4. Refresh data through Doremoveview, delete related data, such as deleting objects in mroot,mdyingviews.
void Doremoveview (Viewrootimpl root) {        synchronized (mLock) {            final int index = mroots.indexof (root);            if (index >= 0) {                mroots.remove (index);                Mparams.remove (index);                Final View view = Mviews.remove (index);                Mdyingviews.remove (view);            }        }        if (Hardwarerenderer.strimforeground && hardwarerenderer.isavailable ()) {            dotrimforeground ();        }    }
3. Update Windowlook at the updateviewlayout in Windowmanagerglobal.
 public void Updateviewlayout (view view, Viewgroup.layoutparams params) {if (view = = null) {throw new Illegala        Rgumentexception ("View must not being null"); } if (! ( params instanceof Windowmanager.layoutparams) {throw new IllegalArgumentException ("params must be Windowmanag Er.        Layoutparams ");        } final Windowmanager.layoutparams wparams = (windowmanager.layoutparams) params;        View.setlayoutparams (Wparams);            Synchronized (mLock) {int index = findviewlocked (view, true);            Viewrootimpl root = mroots.get (index);            Mparams.remove (index);            Mparams.add (index, wparams);        Root.setlayoutparams (Wparams, false); }    }
Update Viewrootimpl's layoutparams with Viewrootimpl's setlayoutparams, then scheduletraversals the view re-layout, including measurement, layout, redrawing, It also updates the window with Windowsession. This process is implemented by Windowmanagerservice. This is similar to the above and will not be repeated. The bottom source of the window to the analysis is finished.



















The underlying principle of Windows add view in Android

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.