From 66cd54a6e62b77e0369da226574819531f201562 Mon Sep 17 00:00:00 2001 From: Luan Nguyen Date: Fri, 13 Feb 2015 11:07:44 -0800 Subject: [PATCH] docs: Remove misleading information about hardware layer performance benefits for optimizing views. bug: 18356775 Change-Id: Ideac15f1eb42fe4c2e291800458bf739cd6a9b4a --- docs/html/training/custom-views/optimizing-view.jd | 132 +++------------------ 1 file changed, 14 insertions(+), 118 deletions(-) diff --git a/docs/html/training/custom-views/optimizing-view.jd b/docs/html/training/custom-views/optimizing-view.jd index 7f2e7620cbfe..022618ba15ce 100644 --- a/docs/html/training/custom-views/optimizing-view.jd +++ b/docs/html/training/custom-views/optimizing-view.jd @@ -12,33 +12,21 @@ previous.link=making-interactive.html

This lesson teaches you to

-
    -
  1. Do Less, Less Frequently
  2. -
  3. Use Hardware Acceleration
  4. -
- -

You should also read

-

Try it out

-
-Download the sample -

CustomView.zip

-
-
+
  • Do Less, Less Frequently
  • + +

    Try it out

    +
    + Download the sample +

    CustomView.zip

    - + +

    Now that you have a well-designed view that responds to gestures and transitions between states, -you need to ensure -that the view runs fast. To avoid a UI that feels sluggish or stutters during playback, you must -ensure that your -animations consistently run at 60 frames per second.

    +ensure that the view runs fast. To avoid a UI that feels sluggish or stutters during playback, +ensure that animations consistently run at 60 frames per second.

    Do Less, Less Frequently

    @@ -52,19 +40,13 @@ would cause a stutter. Allocate objects during initialization, or between animat allocation while an animation is running.

    -

    In addition to making {@link android.view.View#onDraw onDraw()} leaner, you should also make sure +

    In addition to making {@link android.view.View#onDraw onDraw()} leaner, also make sure it's called as infrequently as possible. Most calls to {@link android.view.View#onDraw onDraw()} are the result of a call to {@link android.view.View#invalidate() invalidate()}, so eliminate unnecessary calls to {@link android.view.View#invalidate() -invalidate()}. When possible, call the four-parameter variant of {@link -android.view.View#invalidate() invalidate()} -rather than the version that takes no parameters. The no-parameter variant invalidates the entire -view, while the -four-parameter variant invalidates only a specified portion of the view. This approach allows draw calls to -be more efficient and -can eliminate unnecessary invalidation of views that fall outside the invalid rectangle.

    +invalidate()}.

    Another very expensive operation is traversing layouts. Any time a view calls {@link android.view.View#requestLayout() @@ -78,7 +60,7 @@ behave properly. These deep view hierarchies cause performance problems. Make yo as shallow as possible.

    -

    If you have a complex UI, you should consider writing a custom {@link android.view.ViewGroup +

    If you have a complex UI, consider writing a custom {@link android.view.ViewGroup ViewGroup} to perform its layout. Unlike the built-in views, your custom view can make application-specific assumptions about the size and @@ -88,89 +70,3 @@ to extend {@link android.view.ViewGroup ViewGroup} as part of a custom view. Pie views, but it never measures them. Instead, it sets their sizes directly according to its own custom layout algorithm.

    - -

    Use Hardware Acceleration

    - -

    As of Android 3.0, the Android 2D graphics system can be accelerated by the GPU (Graphics -Processing Unit) hardware -found in most newer Android devices. GPU hardware acceleration can result in a tremendous -performance increase for many -applications, but it isn't the right choice for every application. The Android framework -gives you the ability to finely control which parts of your application are or are not -hardware accelerated.

    - -

    See Hardware Acceleration - in the Android Developers Guide for directions on how to enable acceleration at the - application, activity, or window level. Notice that in addition to the directions in - the developer guide, you must also set your application's target API to 11 or higher by - specifying {@code <uses-sdk - android:targetSdkVersion="11"/>} in your {@code AndroidManifest.xml} file.

    - -

    Once you've enabled hardware acceleration, you may or may not see a performance increase. -Mobile GPUs are very good at certain tasks, such as scaling, rotating, and translating -bitmapped images. They are not particularly good at other tasks, such as drawing lines or curves. To -get the most out of GPU acceleration, you should maximize the number of operations that the GPU is -good at, and minimize the number of operations that the GPU isn't good at.

    - -

    In the PieChart example, for instance, drawing the pie is relatively expensive. Redrawing the pie -each time it's -rotated causes the UI to feel sluggish. The solution is to place the pie chart into a child -{@link android.view.View} and set that -{@link android.view.View}'s - - layer type to {@link android.view.View#LAYER_TYPE_HARDWARE}, so that the GPU can cache it as -a static -image. The sample -defines the child view as an inner class of {@code PieChart}, which minimizes the amount of code -changes that are needed -to implement this solution.

    - -
    -   private class PieView extends View {
    -
    -       public PieView(Context context) {
    -           super(context);
    -           if (!isInEditMode()) {
    -               setLayerType(View.LAYER_TYPE_HARDWARE, null);
    -           }
    -       }
    -       
    -       @Override
    -       protected void onDraw(Canvas canvas) {
    -           super.onDraw(canvas);
    -
    -           for (Item it : mData) {
    -               mPiePaint.setShader(it.mShader);
    -               canvas.drawArc(mBounds,
    -                       360 - it.mEndAngle,
    -                       it.mEndAngle - it.mStartAngle,
    -                       true, mPiePaint);
    -           }
    -       }
    -
    -       @Override
    -       protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    -           mBounds = new RectF(0, 0, w, h);
    -       }
    -
    -       RectF mBounds;
    -   }
    -
    - -

    After this code change, {@code PieChart.PieView.onDraw()} is called only when the view is first -shown. During the rest -of the application's lifetime, the pie chart is cached as an image, and redrawn at different -rotation angles by the GPU. -GPU hardware is particularly good at this sort of thing, and the performance difference is -immediately noticeable.

    - -

    There is a tradeoff, though. Caching images as hardware layers consumes video memory, which is a -limited resource. -For this reason, the final version of {@code PieChart.PieView} only sets its layer type to -{@link android.view.View#LAYER_TYPE_HARDWARE} -while the user is actively scrolling. At all other times, it sets its layer type to -{@link android.view.View#LAYER_TYPE_NONE}, which -allows the GPU to stop caching the image.

    - -

    Finally, don't forget to profile your code. Techniques that improve performance on one view -might negatively affect performance on another.

    -- 2.11.0