Android 4.0 Launcher source code analysis series (2)

Source: Internet
Author: User

In this section, let's take a look at the entire Laucher entry point. What did Laucher do when it loaded its layout file Laucher. xml.
We can find the LauncherApplication in the source code, which inherits the Application class. When the entire Launcher is started, it is the entrance of the entire program. Let's first look at how they are configured in AndroidManifest. xml.
1. <application
2. android: name = "com. android. launcher2.LauncherApplication"
3. android: label = "@ string/application_name"
4. android: icon = "@ drawable/ic_launcher_home"
5. android: hardwareAccelerated = "@ bool/config_hardwareAccelerated"
6. android: largeHeap = "@ bool/config_largeHeap">
First, the Application of the entire Launcher is specified through android: name, that is, the entry is in com. android. in the launcher2.LauncherApplication path, android: lable specifies the name of the desktop as Launcher. If you want to change the name, change the string of the values folder. xml. Android: icon specifies the Laucher icon, which can be seen in the Application Manager, as shown in. It is a cute robot living in a small house. If you need to change the Laucher image, you can reset this attribute.
 
Android: hardwareAccelerated = "@ bool/config_hardwareAccelerated" specifies that hardware acceleration is enabled for the entire application, so that the entire application runs faster.
Android: largeHeap = "@ bool/config_largeHeap" specifies that the application uses a large heap memory to avoid memory out of memory errors to some extent. You can see whether to enable hardware acceleration and large memory configuration in the config. xml file of the values folder. As follows:
1. <bool name = "config_hardwareAccelerated"> true </bool>
2. <bool name = "config_largeHeap"> false </bool>
In the Application, the onCreate () method is passed: sIsScreenLarge = screenSize = Configuration. SCREENLAYOUT_SIZE_LARGE | screenSize = Configuration. SCREENLAYOUT_SIZE_XLARGE; and sScreenDensity = getResources (). getDisplayMetrics (). density; to determine whether it is a large screen and obtain its screen density. At the same time, you can use mIconCache = new IconCache (this); To set the application's Icon cache, and then declare LauncherModel, mModel = new LauncherModel (this, mIconCache ); launcherModel is mainly used to load icons, plug-ins, and folders on the desktop. At the same time, LaucherModel is a broadcast receiver. When the package changes, the region, or configuration file changes, it will send a broadcast to LaucherModel, laucherModel will perform the corresponding loading operations based on different broadcasts. This section will be detailed later.
After LauncherApplication initialization, we came to the onCreate () method of Launcher. java, which is also a series of initialization work when the desktop is started.
The first thing to note is a TraceView debugging method when loading the launcher layout file. It can perform graphical Performance Analysis on the methods between them, and can be specific to the method Code as follows:
1. if (PROFILE_STARTUP ){
2. android. OS. Debug. startMethodTracing (
3. Environment. getDataDirectory () + "/data/com. android. launcher/launcher ");
4 .}
5. if (PROFILE_STARTUP ){
6. android. OS. Debug. stopMethodTracing ();
7 .}
The path for generating performance analysis I specified is/data/com. android. launcher/launcher. After launcher is started, we will find that the launcher is generated under the specified directory. trace file, as shown in:
 
Run the "DDMS pull" command to run the launcher. trace file on the computer. Run the traceview tool in the tools directory of the SDK to open launcher. trace, as shown in:
 
Click to view the chart
It can be seen that setContentView uses 448.623 ms, accounting for 62% of the tracking code time. Therefore, when loading the layout file, it must have passed a series of loading operations. Let's proceed with the analysis.
When loading the launcher layout file, the most critical task is to load the entire workspace. The workspace is a custom component and its inheritance relationship is as follows, we can see that Workspace is actually a ViewGroup and can be added to other controls.
 

When the ViewGroup component is loaded, it first reads the XML file corresponding to the control, and then the Framework layer executes its onMeasure () method, calculate the size of the entire control on the screen based on the size of its child control. Workspace overwrites the onMeasure method of ViewGroup (in PagedView). In workspace, it measures five sub-CellLayout. The method is as follows. For more information, see annotations:
1. @ Override
2. protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec ){
3. if (! MIsDataReady ){
4. super. onMeasure (widthMeasureSpec, heightMeasureSpec );
5. return;
6 .}
7. // get the width (match_parent or wrap_content in the configuration file) and its size
8. final int widthMode = MeasureSpec. getMode (widthMeasureSpec );
9. final int widthSize = MeasureSpec. getSize (widthMeasureSpec );
10. // The width must be match_parent. Otherwise, an exception is thrown.
11. if (widthMode! = MeasureSpec. EXACTLY ){
12. throw new IllegalStateException ("Workspace can only be used in EXACTLY mode .");
13 .}
14.
15./* Allow the height to be set as WRAP_CONTENT. This allows the participates case
16. * of the All apps view on XLarge displays to not take up more space then it needs. Width
17. * is still not allowed to be set as WRAP_CONTENT since into parts of the code against CT
18. * each page to have the same width.
19 .*/
20. // The height is allowed to be wrap_content, because in the case of a large screen, it occupies a redundant position.
21. final int heightMode = MeasureSpec. getMode (heightMeasureSpec );
22. int heightSize = MeasureSpec. getSize (heightMeasureSpec );
23. int maxChildHeight = 0;
24. // obtain the Padding in the vertical and horizontal directions.
25. final int verticalPadding = mPaddingTop + mPaddingBottom;
26. final int horizontalPadding = mPaddingLeft + mPaddingRight;
27.
28.
29. // The children are given the same width and height as the workspace
30. // unless they were set to WRAP_CONTENT
31. if (DEBUG) Log. d (TAG, "PagedView. onMeasure (): "+ widthSize +", "+ heightSize +" mPaddingTop = "+ mPaddingTop +" mPaddingBottom = "+ mPaddingBottom );
32. final int childCount = getChildCount ();
33. // traverse the sub-View of the workspace to measure several of its sub-views.
34. for (int I = 0; I <childCount; I ++ ){
35. // disallowing padding in paged view (just pass 0)
36. final View child = getPageAt (I );
37. final LayoutParams lp = (LayoutParams) child. getLayoutParams ();
38.
39. int childWidthMode;
40. if (lp. width = LayoutParams. WRAP_CONTENT ){
41. childWidthMode = MeasureSpec. AT_MOST;
42.} else {
43. childWidthMode = MeasureSpec. EXACTLY;
44 .}
45.
46. int childHeightMode;
47. if (lp. height = LayoutParams. WRAP_CONTENT ){
48. childHeightMode = MeasureSpec. AT_MOST;
49.} else {
50. childHeightMode = MeasureSpec. EXACTLY;
51 .}
52.
53. final int childWidthMeasureSpec =
54. MeasureSpec. makeMeasureSpec (widthSize-horizontalPadding, childWidthMode );
55. final int childHeightMeasureSpec =
56. MeasureSpec. makeMeasureSpec (heightSize-verticalPadding, childHeightMode );
57. // set the size of the Child View and input the width and height parameters.
58. child. measure (childWidthMeasureSpec, childHeightMeasureSpec );
59. maxChildHeight = Math. max (maxChildHeight, child. getMeasuredHeight ());
60. if (DEBUG) Log. d (TAG, "\ tmeasure-child" + I + ":" + child. getMeasuredWidth () + ","
61. + child. getMeasuredHeight ());
62 .}
63.
64. if (heightMode = MeasureSpec. AT_MOST ){
65. heightSize = maxChildHeight + verticalPadding;
66 .}
67. // store the width and height after measurement
68. setMeasuredDimension (widthSize, heightSize );
69.
70. // We can't call getChildOffset/getRelativeChildOffset until we set the measured dimensions.
71. // We also wait until we set the measured dimensions before flushing the cache as well,
72. // ensure that the cache is filled with good values.
73. invalidateCachedOffsets ();
74. updateScrollingIndicatorPosition ();
75.
76. if (childCount> 0 ){
77. mMaxScrollX = getChildOffset (childCount-1)-getRelativeChildOffset (childCount-1 );
78.} else {
79. mMaxScrollX = 0;
80 .}
81 .}
After the measurement is completed, the Child control can be laid out. At this time, the Framework layer calls the onLayout method that is rewritten in PagedView.
1. @ Override
2. protected void onLayout (boolean changed, int left, int top, int right, int bottom ){
3. if (! MIsDataReady ){
4. return;
5 .}
6.
7. if (DEBUG) Log. d (TAG, "PagedView. onLayout ()");
8. // Padding in the vertical direction
9. final int verticalPadding = mPaddingTop + mPaddingBottom;
10. final int childCount = getChildCount ();
11. int childLeft = 0;
12. if (childCount> 0 ){
13. if (DEBUG) Log. d (TAG, "getRelativeChildOffset ():" + getMeasuredWidth () + ","
14. + getChildWidth (0 ));
15. childLeft = getRelativeChildOffset (0 );
16. // The offset is 0.
17. if (DEBUG) Log. d (TAG, "childLeft:" + childLeft );
18.
19. // Calculate the variable page spacing if necessary
20. // If mPageSpacing is smaller than 0, compress mPageSpacing and assign a value to it.
21. if (mPageSpacing <0 ){
22. setPageSpacing (right-left)-getChildAt (0). getMeasuredWidth ()/2 );
23 .}
24 .}
25.
26. for (int I = 0; I <childCount; I ++ ){
27. final View child = getPageAt (I );
28. if (child. getVisibility ()! = View. GONE ){
29. final int childWidth = getScaledMeasuredWidth (child );
30. final int childchildHeight = child. getMeasuredHeight ();
31. int childTop = mPaddingTop;
32. if (mCenterPagesVertically ){
33. childTop + = (getMeasuredHeight ()-verticalPadding)-childHeight)/2;
34 .}
35.
36. if (DEBUG) Log. d (TAG, "\ tlayout-child" + I + ":" + childLeft + "," + childTop );
37. // layout 5 CellLayout to the corresponding position. The four parameters of layout are left, top, right, and bottom.
38. child. layout (childLeft, childTop,
39. childLeft + child. getMeasuredWidth (), childTop + childHeight );
40. childLeft + = childWidth + mPageSpacing;
41 .}
42 .}
43. // after the first layout, scroll to the default page based on the current page offset (the leftmost distance from the current page to the Workspace ).
44. // The default current page is 3, and its cheap value is the width of two CellLayout.
45. if (mFirstLayout & mCurrentPage> = 0 & mCurrentPage <getChildCount ()){
46. setHorizontalScrollBarEnabled (false );
47. int newX = getChildOffset (mCurrentPage)-getRelativeChildOffset (mCurrentPage );
48. // scroll to the specified position
49. scrollTo (newX, 0 );
50. mScroller. setFinalX (newX );
51. if (DEBUG) Log. d (TAG, "newX is" + newX );
52. setHorizontalScrollBarEnabled (true );
53. mFirstLayout = false;
54 .}
55.
56. if (mFirstLayout & mCurrentPage> = 0 & mCurrentPage <getChildCount ()){
57. mFirstLayout = false;
58 .}
59 .}

Author: LuoXianXion
 

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.