This article simulates three roles: Android architect-Fulamatu, Android control development engineer-small black, Android development engineer-Small white, below three roles to analyze the measure process in different angles.
Xiao Fu is responsible for sharing :
- The essence of measure-OK
- Measure code Flow-Analysis Framelayout.onmeasure
- Onmeasure Method and Measurespec-ok
- Ask questions
Android Architect-Fulamatu Share
I. The essence of Measure
Fulamatu: I share today Yes measure architecture design related, first ask a question, what is the nature of measure?
Little black: This I know, is the first step of the measure, layout, draw three steps of the Android system to create the UI interface, mainly for measuring the view size, in more detail is the "relative value" (Wrap_content, Fill_parent, Match_ PARENT) into the process of the specific reference.
Fulamatu: Little Black is right, ask another question, what does the view size mean?
Small white: The view size is the size of the view on the screen, that is, when developed by Layout_width and Layout_heigh set?
Fulamatu: Little White says only one of them as a developer's angle. Android system design Canvas is infinite, if a screen size is 320 * 480, but layout_width= "480px", layout_heigh= "800px", it is obvious that the width of the view is larger than the actual screen size. The question is, is the size of the view displayed on the screen, or the actual size of the view (even if the screen size is exceeded)?
Small black: The specific view display size is set by the developer, then by my control development engineer in Onmeasure decided, if to Fulamatu said size, even if more than the screen I can decide is width=, Heigh = 480 or widt= 480, Heigh = 800, It's up to me to write a demo when I share it. (views are categorized according to drawing size: content view, graphical view)
Little white: What is canvas? Fulamatu: This is discussed in detail after sharing the draw process, which can be broadly understood as the canvas used for drawing.
second, measure code flow
Fulamatu: First look at the measure execution process from the source to see what has been done in these processes. The following are the source code in the Android.view.ViewRootImpl.java class
Public final class Viewrootimpl extends Handler implements Viewparent, View.AttachInfo.Callbacks, Hardwarerenderer. Hardwaredrawcallbacks {///1 All child views of the Requestlayout method, most often trigger the root view of this method public void Requestlayout () {checkthread (); Need to re-layout mlayoutrequested = true; Scheduletraversals (); }//Schedule traverse public void Scheduletraversals () {if (!mtraversalscheduled) {mtraversalscheduled = Tru E ...//The current class inherits from Handler, sending an empty message to join the message Queue sendemptymessage (do_traversal); }} @Override public void Handlemessage (Message msg) {switch (msg.what) {... case do_trave RSAL: ...//handling Do_traversal message performtraversals (); ... break, ...} }//execute traverse private void Performtraversals () {final View host = MView; int desiredwindowwidth; int desiredwindowheight; int ChildwidthmeasurespEc int childheightmeasurespec; .... if (mlayoutrequested &&!mstopped) {... childwidthmeasurespec = Getrootmea Surespec (Desiredwindowwidth, lp.width); Childheightmeasurespec = Getrootmeasurespec (Desiredwindowheight, lp.height); ...//host is a View object Host.measure (Childwidthmeasurespec, Childheightmeasurespec); ...... } ...... }}
Note: The Getrootmeasurespec method in the above code can be either Childwidthmeasurespec with Childheightmeasurespec in the view, It is interesting to look at the assignment of the desiredwindowwidth variable to get the width height of the window.
The above code is divided into 5 steps 1 requestlayout (), 2 scheduletraversals (), 3 Handlemessage (), 4 performtraversals (), 5 ho St.measure (Childwidthmeasurespec, Childheightmeasurespec);
- All views in the interface perform Requestlayout, and the re-layout request is progressively passed up, culminating in the execution of the current Viewrootimpl requestlaout ()
- Step 1 will execute scheduletraversals, where an empty message is sent, the re-layout request is sent through handler to the main thread of the Meassqueue waiting for execution (specifically can learn handler).
- Because the current viewrootimpl is inherited from the handler, the handlemessage method is searched directly, because the message passed is do_traversal, and the branch calls Performtraversals
- The Performtraversals method calls Host.measure (Childwidthmeasurespec, Childheightmeasurespec);
- Because host is a view object, the next step is to look at the View.measure method to further analyze the measure process
Then the fifth step of the above measure process goes down, the following is the source code in the Android.view.View.java file:
public class View implements Drawable.callback, Drawable.callback2, Keyevent.callback, Accessibilityeventsource { Method is final type, description cannot overwrite or reload public final void measure (int widthmeasurespec, int heightmeasurespec) {//If there is a re-request flag Change if (mprivateflags & force_layout) = = Force_layout | | Widthmeasurespec! = Moldwidthmeasurespec | | Heightmeasurespec! = Moldheightmeasurespec) {...//really perform a measurement view size operation//measure ourselves , this should set the measured dimension flag back onmeasure (Widthmeasurespec, Heightmeasurespec); ...//Add re-request child view layout flag mprivateflags |= layout_required; } ...... } /** * The something has changed which have invalidated the * layout of this view. This would schedule a layout pass of the view * tree. */public void Requestlayout () {if (viewdebug.trace_hierarchy) {ViewDebug.trace (this, ViewDebug.HierarchyTraceType.REQUEST_LAYOUT); }//Add re-request layout flag mprivateflags |= force_layout; Mprivateflags |= invalidated; if (mparent! = null) {if (mlayoutparams! = null) {mlayoutparams.resolvewithdirection (getresolv Edlayoutdirection ()); } if (!mparent.islayoutrequested ()) {mparent.requestlayout (); } } }}
The measure process of the above code can be divided into 4 steps
1 measure and Requestlayout, 2 onmeasure
- The measure method is the final type, stating that this method cannot be modified. Where the judging condition (mprivateflags & force_layout) = = Force_layout value is assigned in Requestlayout. The second step is triggered as long as the measurement's wide and high changes.
- Implement the current Onmeasure method, through the hierarchy Viewer and other tools can learn that the root view is the Framelayout type (this is not verified from the source code)
And then look at the Android.widget.FrameLayout class of onmeasure always do what?
Third, the Onmeasure method and measurespec the code shown above the parameter int widthmeasurespec, the int heightmeasurespec is uniformly processed by the Measurespec class. Measurespec is an internal class of Android.view.View that encapsulates the layout requirements information that is passed from the parent class to the subclass. Each Measurespec object describes the height or width of the space. The Measurespec is made up of size and mode.
1. Introduction of Measurespec Method:
Class name. Method Name |
Explain |
Measurespec.getmode (int measurespec) |
Extraction mode According to the measured value (format) provided (one of the three modes above) |
measurespec.getsize (int measurespec) |
Extract the size value based on the measured value (format) provided |
Measurespec.makemeasurespec (int size,int mode) |
Creates a measure (format) based on the provided size value and pattern |
2. Measurespec has three modes, respectively, and describes the corresponding relationship between the mode and layout parameter values.
Mode |
Translation |
Model and layout parameter correspondence relation |
Pattern description |
UNSPECIFIED |
Unlimited |
|
Parent view does not constrain the size of the child view |
At_most |
Most of |
Wrap_content |
Child view can take values within the parent view range |
Exactly |
Accuracy of |
Fill_parent (e.g. 50dip) |
Parent view specifies a fixed size for child view |
3. Measurespec to get mode and sieze from values of type int by bit runFor more detailed analysis please see "Android Onmeasure, one of the deep understanding layouts!"
Iv. Ask the question why does the layout need a parent view and a child view to decide together? Why not set width and height directly? If this is not the case, specify a fixed size like HTML, which will cause one to go through a lot of other extrusion. Because HTML is control over the entire page. While Android is split, this ensures that the end-of-the-line (interface development) affects the layout of the other tiers and needs to follow (control development) rules. View.setwidth, View.setheight? No
Need to pass Measurechilde (view, width, height), or childview.measure ();
What else is there? View.getwidth (), View.gethight ()
View.getmeasurewidth (), View.getmeasurehiegh ()
One that was not added to the view? But sometimes the getmesureheight still returns 0. Why?
Android View measure (i) Process analysis