Analysis of some optimization points of view drawing in Android Application Development

A common misconception is that using basic layout structures (such as linear layout, FrameLayout, etc.) can produce efficient layout in most cases. Obviously, every control and layout added in your application needs initialization, layout and drawing. For example: embedding a LinearLayout will produce a layout hierarchy that is too deep. What's more, several embedded use layout_ The LinearLayout of the weight attribute will cause a lot of overhead because each sub view needs to be measured twice. This is an important point when repeatedly parsing layout files, such as when used in listview or GridView.

Observe your layout. The Android SDK toolkit includes a tool called "hierarchy viewer", which allows you to analyze the layout while your application is running. Using this tool can help you find bottlenecks in your layout efficiency. The "hierarchy viewer" tool allows you to select running processes from connected devices or simulators, and then present a layout tree. The traffic lights under each square (see the figure below) - red, green and blue show the efficiency value in the process of measurement, layout and drawing, which can help you locate potential problems. Suppose an item in the listview has the following layout (see Figure 1):

The "hierarchy viewer" tool can be found in the < SDK > / tools path. When it is opened, the hierarchy viewer tool displays all available devices and processes running on them. Click "load view hierarchy" to display the UI layout hierarchy of a component you select. For example, figure 2 shows the layout hierarchy tree of Figure 1.

In Figure 2, you can see that there are some problems with the three-tier layout structure. Click items reflect the time consumption in each measurement, layout, and drawing process (see Figure 3). Obviously, this item (linear layout) takes the longest time to measure, layout and draw, and you should spend some energy on optimizing them.

The rendering time of the layout file is: measurement process: 0.977ms layout process: 0.167ms drawing process: 2.717ms modifying the layout file. The low efficiency of the layout in the above figure is due to an embedded LinearLayout control. By flattening the layout file, the layout becomes shallower and wider rather than narrower and deeper, This will improve efficiency. A relativelayout as the root node can also provide the above layout effect (i.e. Figure 1). Therefore, using relativelayout to change the layout design, you can see that our layout level is only 2 layers now. The new layout hierarchy tree is as follows:

Now, the time to complete the rendering of the layout file is: measurement process: 0.977ms layout process: 0.167ms drawing process: 2.717ms. Maybe it is only a small improvement, but this time it will be called many times, because listview will layout all items. Accumulated, the improved effect is still very considerable.

Most of the time difference is due to the use of layout_ LinearLayout of weight attribute, which can slow down the measurement process. This is just an example, that is, each layout should be used appropriately, and you should seriously consider whether it is necessary to adopt the "layout_weight" attribute. Use the lint tool

A good practice is to use the lint tool in your layout file to find ways to optimize the layout hierarchy. Lint has replaced the layoutopt tool and it provides more powerful functions. Some lint rules are as follows:

1. Use composite control - the LinearLayout containing an ImageView and a textview control will be handled more effectively if it can be used as a composite control. 2. Merge the frame layout as the root node -- if a frame layout is the root node in the layout file and it has no background picture or padding, a more effective way is to replace the < FrameLayout / > label with the < merge / > label.

3. Useless leaf node - generally speaking, if a layout control has no child view or background picture, the layout control can be removed (because it is in invisible state). 4. Useless parent node - if a parent view has child views but no sibling view nodes, the view is not a Scrollview control or root node, and it has no background picture, it can also be removed. After removal, all child views of the parent view are directly moved to the layout level of the previous parent view. It can also make parsing layout and layout hierarchy more effective. 5. Too deep layout level - too many embedded layouts are always inefficient. Consider using some flat layout controls, such as relativelayout and GridLayout, to improve the layout process. The default maximum layout depth is 10. When developing in the eclipse environment, lint can automatically solve some problems, provide some suggestions, and jump directly to the wrong code for verification. If you don't use eclipse, lint can also run from the command line. Use the < include / > tag to reuse layout files. Although Android provides small and reusable interactive elements through built-in various controls, you may need to reuse larger components -- some specific layout files. In order to reuse layout files more efficiently, you can use the < include / > and < merge / > tags to add other layout files to the current layout file.

Reusing layout files is a particularly powerful method that allows you to create reusable layout files. For example, a button panel containing "yse" or "no" or a ProgressBar with a text description. Reusing layout files also means that any element in your application can be extracted from complex layout files for separate management. Then all you need to do is add these independent layout files (because they are reusable). Therefore, when you create an independent UI component through a custom view, you can reuse the layout file to make things easier.

1. Create a reusable layout file

If you already know the "face" of reuse layout, create and define layout files (named after ". XML"). For example, here is a layout file from G - Kenya codelab, which defines a custom title (titlebar. XML) to be used in each activity: since these reusable layouts are added to other layout files, each root view should be accurate.

2. Use the < include / > tag

Use the < include / > tag where you need to add these layouts. For example, the following is a layout file from g-kenya codelab, which reuses the "title bar" file listed above. The layout file is as follows:

You can also define a special ID for the root view of the added layout file in the < include / > node and override all layout parameters (any attribute prefixed with "Android: layout_). For example:

3. Use the < merge / > tag

When reusing another layout in the layout file, < merge / > tags can eliminate redundant view elements at the layout level. For example, if your main layout file is a LinearLayout containing two views vertically, the layout can be reused in other layouts, and a root view is required for any layout file containing two views (otherwise, the compiler will prompt an error). However, adding a LinearLayout as the root view in this reusable layout will result in a vertical LinearLayout containing another vertical LinearLayout. Inline LinearLayout can only slow down UI efficiency, and others are useless. The reusable layout is presented as follows using. XML:

To avoid redundant layout elements, you can use < merge / > as the root view of the reusable layout file. For example: layout file using < merge / > tag:

Now, when you add the layout file (using the < include / > tag), the system ignores the < merge / > node and directly adds two buttons to replace the < include / > node. The less the better

To speed up the view, reduce unnecessary code from activities that call frequently. Start drawing in the OnDraw () method, which will give you the greatest benefit. Especially low, you should also reduce the memory allocation in the OnDraw () method, because any memory allocation may lead to memory recycling, which will cause incoherence. Assign objects between initialization or animation. Never allocate memory while the animation is running.

On the other hand, you need to reduce the overhead in the OnDraw () method and call the OnDraw () method only when needed. Normally, the invalidate () method calls the OnDraw () method, thus reducing unnecessary calls to invalidate (). If possible, call its overloaded version, the invalidate () method with parameters instead of the invalidate () method without parameters. The method invalidate () with parameters can make the drawing process more effective and reduce unnecessary redrawing of views falling outside the rectangular area (the area specified by the parameters).

Note: the three overloaded versions of invalidate() are: 1. Public void invalidate (rect dirty) 2. Public void invalidate (Int l, int t, int r, int b) 3. Public void invalidate ()

Another costly operation is the layout process. Whenever the requestlayout () method is called on the view, the Android UI framework needs to traverse the entire view tree to determine the size of each view. If there is any conflict during the measure process, the view tree may be traversed multiple times. UI designers sometimes create deeper viewgroups to achieve certain effects. But these deep-seated view trees can cause efficiency problems. Make sure your view tree is as shallow as possible.

If your UI design is complex, you should consider designing a custom ViewGroup to implement the layout process. Unlike the built-in view control, a custom view can assume the size and shape of each child view, and can avoid the measure process for each child view. Piechart shows how to inherit the ViewGroup class. Piechart has child views, but it never measures them. On the contrary, it directly sets the size of each sub view according to its own layout algorithm. The following code is shown:

Using hardware acceleration

After Android version 3.0, the Android 2D graphics library can use GPU (graphics processing unit) acceleration on most Android devices. GPU hardware acceleration can greatly optimize most applications, but it is not the best choice for each application. The Android framework gives you control over whether to use hardware acceleration in your applications.

It should be noted that we must manually set the application API level to 11 or higher in the configuration file, that is, configure androidmanifest.xml as follows:

Once you turn on hardware acceleration, you may not see an increase in efficiency. Mobile GPUs is good at handling specific tasks, such as scaling, rotating and panning pictures. It also has some tasks that it is not good at, such as drawing lines or curves. As the saying goes, make the best use of everything, develop strengths and avoid weaknesses, let the GPU handle the tasks it is good at as much as possible, and reduce the time for it to handle vulnerable tasks.

In the piechart example, for example, drawing a circle is relatively resource consuming. Redrawing caused by each rotation results in slow UI. The solution is to let the view render the circle, and set the layer type attribute of the view to layer_ TYPE_ Hardware, so GPU can cache static pictures. In the example, the view exists as an internal class of the piechart class, reducing the code overhead for implementing this method.

After the change, the piechart. Pieview. OnDraw () method will be called only when the view is displayed for the first time. At other times of the application, the drawn image will be cached as an image, and the GPU will rotate the image arbitrarily when redrawing.

However, this is only a compromise. Caching pictures as a hardware layer leads to video memory overhead, but video memory is a limited resource. For this reason, on the final version of piechart.pieview, its layer type attribute is set to layer only when the user slides_ TYPE_ HARDWARE。 At other times, just set its layer type attribute to layer_ TYPE_ Hardware, which allows the GPU to stop caching pictures.

Finally, don't forget to analyze your code. The optimization technology on one view may have a bad impact on other views.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>