The Activitythread#performlaunchactivity method is executed during the activation of the activity, where Activity#attach is called. Instantiating the Mwindow property held by activity in the attach () method is the only implementation class Phonewindow for window.
ActivityThread#performLaunchActivity private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... activity.attach(...); ... } Activity#attach attach(...) { ... mWindow = new PhoneWindow(this, window); mWindow.setWindowManager(...); mWindowManager = mWindow.getWindowManager(); ... }
In Activitythread#handleresumeactivity, after calling Activity#onresume through the Activitythread#performresumeactivity method, The Decorview will be acquired and added to the Viewrootimpl via WindowManager.
final void handleresumeactivity ( ... ) { R = performresumeactivity (token, clearhide, reason); R.window = R.activity.getwindow (); View decor = R.window.getdecorview (); Decor.setvisibility (view.invisible); Viewmanager wm = A.getwindowmanager (); A.mdecor = Decor; Wm.addview (decor, L); ... R.activity.makevisible (); ... } phonewindow #getDecorView public final View Getdecorview () {if (Mdecor = = NULL | | mforcedecorinstall) {installdecor (); } return Mdecor; }
R.activity.getwindow () returns the Phonewindow object that is instantiated in Activity#attach. Then call Phonewindow#getdecorview to get the Decorview object, see the Android setcontentview () source code parsing. The Decorview is then populated but is set to invisible (visible through the r.activity.makevisible () setting), and the Decorview is added to the Viewrootimpl by Windowmanager#addview. Viewrootimpl The following will be carefully analyzed, the process of AddView refer to Android using WindowManager to realize the suspension window and source code analysis. Careful classmate may notice at this time Decorview just add to viewroot through Windowmanger#addview, in fact this also explains why say "in OnCreate to Onresume process, activity already to system visible, But there's no reason to show the interface. The Decorview is not added to the window at this point because the activity is loaded and the Attach, OnCreate, OnStart, and even the onresume are executed. OnCreate, OnStart, and onresume do not get the control's height because of this reason, layout, viewroot, draw is not really executed until windowmanager#addview (internal instantiation of measure).
Decorview is a subclass of Framelayout, which is also inherited from view. The rest of the XML View/viewgroup are added into the decorview belongs to the "Add View/viewgroup viewgroup" type, not representative, interested in the Android XML layout file parsing process source parsing.
If you call the Setcontentview () method in Activity#oncreate, the Decorview is created directly. If you do not call the Setcontentview () method, Decorview is automatically created in activitythread#handleresumeactivity through R.window.getdecorview (). In short, no matter what you create in the activity, there will always be Decorview created by Phonewindow. The function of Phonewindow is to manipulate view,activity calls Findviewbyid similar methods are to manipulate the view indirectly through Phonewindow. Thus, Decorview is associated with the activity as the top view of the view tree through Phonewindow.
In the process of Windowmanger#addview, the Viewrootimpl#addview is called.
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this) { if (mView == null) { ... mView = view; requestLayout(); res = mWindowSession.addToDisplay(...); ... } } }
The
Assigns the incoming view to the global property Mview first, and then uses the Mview property to manipulate the Decorview. The Mwindowsession.addtodisplay process has been resolved in the use of Android WindowManager to realize the floating window and source code parsing, A brief description of the function is to add the window to the Windowmanagerservice Mwindowmap property for management. Requestlayout () This method is very powerful, you may be able to customize the view, you may have seen the three processes of view drawing (measure, layout, draw), but do you know the source of these things? Yes, it's all in Requestlayout (). Insert a digression, through the above code can be found, Phonewindow is not directly operated Decorview, in the middle is also separated by a viewrootimpl.
@Override public void requestlayout () {if (!mhandlinglayoutinlayoutrequest) {checkthread (); mlayoutrequested = true ; Scheduletraversals (); }} void checkthread () {if (mthread! = T Hread.currentthread ()) {throw new CalledFr Omwrongthreadexception ( "only the original thread that created a view Hierarc Hy can touch its views. ");}}
It is common to update the UI in a child thread, which can cause errors in checkthread. But looking closely at this method, Mthread is instantiated at initialization Viewrootimpl, equal to the thread that created the Viewrootimpl. Normally we are viewrootimpl created on the main thread, and in fact can be created in a child thread, such as creating a toast. Toast is also a window, refer to Android Advanced custom toast and source parsing. But Thread.CurrentThread () is the thread that updates the UI. What happens if both of these two are in a child thread? Nothing is going to happen. Yes, a child thread can update the UI. However, the creation line threads of the UI requires that only Viewrootimpl created by the child thread can update the UI in the child thread. The sample code for the child thread update UI is as follows:
New Thread (New Runnable () {@Override public void run () {Looper. Prepare();Toast. Maketext(mainactivity. this,"A mouthful of three buns", Toast. LENGTH_short). Show();New Alertdialog. Builder(mainactivity. this). Settitle("Game of Thrones"). Setmessage("Winter is Coming"). Setpositivebutton("Yes,my Lord", null). Show();Looper. Loop();} }). Start();
Scheduletraversals () method is called through layers (mtraversalrunnable->dotraversal->performtraversals)
Private void performtraversals() {FinalView host = MView; Performmeasure (Childwidthmeasurespec, Childheightmeasurespec); PERFORMLAYOUT (LP, Mwidth, Mheight); Performdraw (); }Private void performmeasure(intChildwidthmeasurespec,intChildheightmeasurespec) {mview.measure (Childwidthmeasurespec, Childheightmeasurespec); }Private void PerformLayout(Windowmanager.layoutparams LP,intDesiredwindowwidth,intDesiredwindowheight) {FinalView host = MView; Host.layout (0,0, Host.getmeasuredwidth (), Host.getmeasuredheight ()); }Private void Performdraw() {//Draw (fullredrawneeded)-DrawsoftwareMview.draw (canvas); }
The Performtraversals method is long, which only captures the starting point of the three main processes of view drawing. Mview is the previously cached Decorview. Then began the view of the measure, layout, draw, Onmeasure, OnLayout, OnDraw ...
More framework source code Analysis, please visit the framework Source code parsing series [catalog]
Android top View Decorview's past life