【我的Android进阶之旅】关于自定义View的时候,使用了Xfermode而调用了禁用硬件加速的注意事项

一、问题描述

在博客

里面我绘制了一个自定义View,如下图所示:

但是,由于使用了PorterDuffXfermode来处理两个图层的图层混合模式,而网上的资料说

  • https://blog.csdn.net/wingichoy/article/details/50534175
    在这里插入图片描述
  • https://www.jianshu.com/p/78c36742d50f
    在这里插入图片描述

都说在使用Xfermode时,为了保险起见,都要禁用硬件加速。

因此我就将禁用硬件加速的代码加入到了自定义View的代码中

 //禁用硬件加速
 setLayerType(View.LAYER_TYPE_SOFTWARE, null);

如下所示:

 @Override
    protected void onDraw(Canvas canvas) {
        //制成一个白色的圆角矩形  作为背景  画2个半圆 和 18个小圆  作为分隔线
        initWidthAndHeight();
        //禁用硬件加速
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        //使用离屏绘制  存为新图层
        int layerID = canvas.saveLayer(0, 0, mWidth, mHeight, backGroundPaint, Canvas.ALL_SAVE_FLAG);

        // 绘制目标图
        drawLeftAndRightBigHalfCircle(canvas);
        // 设置图层混合模式
        backGroundPaint.setXfermode(mXfermode);
        // 绘制源图
        drawBackGroundAndSmallCircle(canvas);
        // 清除混合模式
        backGroundPaint.setXfermode(null);
        // 恢复保存的图层;
        canvas.restoreToCount(layerID);
        // ==========================    第四步、 让RelativeLayout绘制自己
        super.onDraw(canvas);
    }

在这里插入图片描述

完整的代码如下:

package com.oyp.view;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;


public class CustomOypRoundLinearLayout extends LinearLayout {
    /**
     * 大圆、小圆的圆心的Y坐标
     */
    private int circleStartY;
    /**
     * 第一个小圆的圆心的X坐标
     */
    private int smallCircleStartX;
    /**
     * 小圆的个数
     */
    private int smallCircleCount;
    /**
     * 小圆的半径
     */
    private int smallCircleRadius;
    /**
     * 小圆之间的间距
     */
    private int smallCircleMargin;
    /**
     * 大圆的半径
     */
    private int bigCircleRadius;
    /**
     * 背景的圆角
     */
    private int backgroundRadius;
    /**
     * 背景的背景颜色
     */
    private int backgroundColor;
    /**
     * 小圆的颜色
     */
    private int smallCircleColor;
    /**
     * 大圆的颜色
     */
    private int bigCircleColor;

    private RectF backGroundRectF;
    private Paint backGroundPaint;
    private Paint circlePaint;

    private RectF leftOval;
    private RectF rightOval;

    private int mWidth;
    private int mHeight;
    private PorterDuffXfermode mXfermode;

    public CustomOypRoundLinearLayout(Context context) {
        this(context, null);
    }

    public CustomOypRoundLinearLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomOypRoundLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @TargetApi(21)
    public CustomOypRoundLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private void init(Context context, @Nullable AttributeSet attrs) {
        //初始化自定义属性
        initTypeArray(context, attrs);
        //想要重写onDraw,就要调用setWillNotDraw(false)
        //ViewGroup默认情况下,出于性能考虑,会被设置成WILL_NOT_DROW,这样,ondraw就不会被执行了。
        // 如果我们想重写一个viewgroup的ondraw方法,有两种方法:
        // 1,构造函数中,给viewgroup设置一个颜色。
        // 2,构造函数中,调用setWillNotDraw(false),去掉其WILL_NOT_DRAW flag。
        // 在viewgroup初始化的时候,它调用了一个私有方法:initViewGroup,它里面会有一句setFlags(WILLL_NOT_DRAW,DRAW_MASK);
        // 相当于调用了setWillNotDraw(true),所以说,对于ViewGroup,他就认为是透明的了,
        // 如果我们想要重写onDraw,就要调用setWillNotDraw(false)
        setWillNotDraw(false);

        initPaint();
        initXfermode();
        initRectF();
    }

    private void initPaint() {
        backGroundPaint = new Paint();
        backGroundPaint.setColor(backgroundColor);

        circlePaint = new Paint();
        circlePaint.setStyle(Paint.Style.FILL);
        circlePaint.setColor(bigCircleColor);
    }

    private void initXfermode() {
        //禁用硬件加速   https://www.jianshu.com/p/78c36742d50f
        //从硬件加速不支持的函数列表中,我们可以看到AvoidXfermode,PixelXorXfermode是完全不支持的,而PorterDuffXfermode是部分不支持的。
        //如果你的APP跑在API 14版本以后,而你洽好要用那些不支持硬件加速的函数要怎么办? 那就只好禁用硬件加速喽

        //该方法千万别放到onDraw()方法里面调用,否则会不停的重绘的,因为该方法调用了invalidate() 方法
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        mXfermode = new PorterDuffXfermode(PorterDuff.Mode.XOR);
    }

    private void initRectF() {
        backGroundRectF = new RectF();
        leftOval = new RectF();
        rightOval = new RectF();
    }

    private void initWidthAndHeight() {
        mWidth = getWidth();
        mHeight = getHeight();
    }

    private void initTypeArray(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomOypRoundLinearLayout);
        //个数
        smallCircleCount = typedArray.getInteger(R.styleable.CustomOypRoundLinearLayout_smallCircleCount,
                getResources().getInteger(R.integer.smallCircleCount));
        //尺寸
        circleStartY = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_circleStartY,
                getResources().getDimensionPixelOffset(R.dimen.circleStartY));
        smallCircleStartX = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_smallCircleStartX,
                getResources().getDimensionPixelOffset(R.dimen.smallCircleStartX));
        smallCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_smallCircleRadius,
                getResources().getDimensionPixelOffset(R.dimen.smallCircleRadius));
        bigCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_bigCircleRadius,
                getResources().getDimensionPixelOffset(R.dimen.bigCircleRadius));
        backgroundRadius = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_backgroundRadius,
                getResources().getDimensionPixelOffset(R.dimen.backgroundRadius));
        //颜色
        backgroundColor = typedArray.getColor(R.styleable.CustomOypRoundLinearLayout_backgroundColor,
                getResources().getColor(R.color.backgroundColor));
        smallCircleColor = typedArray.getColor(R.styleable.CustomOypRoundLinearLayout_smallCircleColor,
                getResources().getColor(R.color.smallCircleColor));
        bigCircleColor = typedArray.getColor(R.styleable.CustomOypRoundLinearLayout_bigCircleColor,
                getResources().getColor(R.color.bigCircleColor));
        //回收typedArray
        typedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //制成一个白色的圆角矩形  作为背景  画2个半圆 和 18个小圆  作为分隔线
        initWidthAndHeight();

        //使用离屏绘制  存为新图层
        int layerID = canvas.saveLayer(0, 0, mWidth, mHeight, backGroundPaint, Canvas.ALL_SAVE_FLAG);

        // 绘制目标图
        drawLeftAndRightBigHalfCircle(canvas);
        // 设置图层混合模式
        backGroundPaint.setXfermode(mXfermode);
        // 绘制源图
        drawBackGroundAndSmallCircle(canvas);
        // 清除混合模式
        backGroundPaint.setXfermode(null);
        // 恢复保存的图层;
        canvas.restoreToCount(layerID);
        // ==========================    第四步、 让RelativeLayout绘制自己
        super.onDraw(canvas);
    }

    private void drawBackGroundAndSmallCircle(Canvas canvas) {
        // ========================== 绘制白色矩形
        backGroundRectF.set(0, 0, mWidth, mHeight);
        canvas.drawRoundRect(backGroundRectF, backgroundRadius, backgroundRadius, backGroundPaint);

        // ==========================  绘制19个小圆  作为分隔线
        // 最后一个小圆和第一个小圆之间 有18段分隔空白
        smallCircleMargin = ((mWidth - smallCircleStartX) - (smallCircleStartX)) / (smallCircleCount - 1);
        circlePaint.setColor(smallCircleColor);
        for (int i = 0; i < smallCircleCount; i++) {
            canvas.drawCircle(smallCircleStartX + i * smallCircleMargin, circleStartY, smallCircleRadius, circlePaint);
        }
    }

    private void drawLeftAndRightBigHalfCircle(Canvas canvas) {
        // ========================== 绘制2个半圆
        leftOval.set(-bigCircleRadius, circleStartY - bigCircleRadius,
                bigCircleRadius, circleStartY + bigCircleRadius);
        /*
         * drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
         * oval :指定圆弧的外轮廓矩形区域。
         * startAngle: 圆弧起始角度,单位为度。
         * sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度,从右中间开始为零度。
         * useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。关键是这个变量,下面将会详细介绍。
         * paint: 绘制圆弧的画板属性,如颜色,是否填充等。
         */
        //左边的半圆
        canvas.drawArc(leftOval, -90, 180, true, circlePaint);

        //右边的半圆
        rightOval.set(mWidth - bigCircleRadius, circleStartY - bigCircleRadius,
                mWidth + bigCircleRadius, circleStartY + bigCircleRadius);
        canvas.drawArc(rightOval, 90, 180, true, circlePaint);
    }
}

1.1 问题来了,不停地重绘

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.2 分析原因

/**
     * <p>Specifies the type of layer backing this view. The layer can be
     * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
     * {@link #LAYER_TYPE_HARDWARE}.</p>
     *
     * <p>A layer is associated with an optional {@link android.graphics.Paint}
     * instance that controls how the layer is composed on screen. The following
     * properties of the paint are taken into account when composing the layer:</p>
     * <ul>
     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
     * </ul>
     *
     * <p>If this view has an alpha value set to < 1.0 by calling
     * {@link #setAlpha(float)}, the alpha value of the layer's paint is superseded
     * by this view's alpha value.</p>
     *
     * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE},
     * {@link #LAYER_TYPE_SOFTWARE} and {@link #LAYER_TYPE_HARDWARE}
     * for more information on when and how to use layers.</p>
     *
     * @param layerType The type of layer to use with this view, must be one of
     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
     *        {@link #LAYER_TYPE_HARDWARE}
     * @param paint The paint used to compose the layer. This argument is optional
     *        and can be null. It is ignored when the layer type is
     *        {@link #LAYER_TYPE_NONE}
     *
     * @see #getLayerType()
     * @see #LAYER_TYPE_NONE
     * @see #LAYER_TYPE_SOFTWARE
     * @see #LAYER_TYPE_HARDWARE
     * @see #setAlpha(float)
     *
     * @attr ref android.R.styleable#View_layerType
     */
    public void setLayerType(int layerType, @Nullable Paint paint) {
        if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
            throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
                    + "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
        }

        boolean typeChanged = mRenderNode.setLayerType(layerType);

        if (!typeChanged) {
            setLayerPaint(paint);
            return;
        }

        if (layerType != LAYER_TYPE_SOFTWARE) {
            // Destroy any previous software drawing cache if present
            // NOTE: even if previous layer type is HW, we do this to ensure we've cleaned up
            // drawing cache created in View#draw when drawing to a SW canvas.
            destroyDrawingCache();
        }

        mLayerType = layerType;
        mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : paint;
        mRenderNode.setLayerPaint(mLayerPaint);

        // draw() behaves differently if we are on a layer, so we need to
        // invalidate() here
        invalidateParentCaches();
        invalidate(true);
    }

在这里插入图片描述

android.view.View#setLayerType 方法调用了 android.view.View#invalidate(boolean) 方法,所以导致了重绘
在这里插入图片描述

 /**
     * Invalidate the whole view. If the view is visible,
     * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
     * the future.
     * <p>
     * This must be called from a UI thread. To call from a non-UI thread, call
     * {@link #postInvalidate()}.
     */
    public void invalidate() {
        invalidate(true);
    }

    /**
     * This is where the invalidate() work actually happens. A full invalidate()
     * causes the drawing cache to be invalidated, but this function can be
     * called with invalidateCache set to false to skip that invalidation step
     * for cases that do not need it (for example, a component that remains at
     * the same dimensions with the same content).
     *
     * @param invalidateCache Whether the drawing cache for this view should be
     *            invalidated as well. This is usually true for a full
     *            invalidate, but may be set to false if the View's contents or
     *            dimensions have not changed.
     * @hide
     */
    public void invalidate(boolean invalidateCache) {
        invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
    }

所以原因就是

在onDraw()方法中调用了android.view.View#setLayerType(int layerType, @Nullable Paint paint)** 方法
.而 android.view.View#setLayerType(int layerType, @Nullable Paint paint) 方法调用了 android.view.View#invalidate(boolean invalidateCache) 方法,
所以导致了不停地重绘

1.3 解决这个坑

setLayerType(View.LAYER_TYPE_SOFTWARE, null); 放到初始化的地方去调用,只调用一次。
在这里插入图片描述
完整代码如下

package com.oyp.view;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;


public class CustomOypRoundLinearLayout extends LinearLayout {
    /**
     * 大圆、小圆的圆心的Y坐标
     */
    private int circleStartY;
    /**
     * 第一个小圆的圆心的X坐标
     */
    private int smallCircleStartX;
    /**
     * 小圆的个数
     */
    private int smallCircleCount;
    /**
     * 小圆的半径
     */
    private int smallCircleRadius;
    /**
     * 小圆之间的间距
     */
    private int smallCircleMargin;
    /**
     * 大圆的半径
     */
    private int bigCircleRadius;
    /**
     * 背景的圆角
     */
    private int backgroundRadius;
    /**
     * 背景的背景颜色
     */
    private int backgroundColor;
    /**
     * 小圆的颜色
     */
    private int smallCircleColor;
    /**
     * 大圆的颜色
     */
    private int bigCircleColor;

    private RectF backGroundRectF;
    private Paint backGroundPaint;
    private Paint circlePaint;

    private RectF leftOval;
    private RectF rightOval;

    private int mWidth;
    private int mHeight;
    private PorterDuffXfermode mXfermode;

    public CustomOypRoundLinearLayout(Context context) {
        this(context, null);
    }

    public CustomOypRoundLinearLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomOypRoundLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @TargetApi(21)
    public CustomOypRoundLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private void init(Context context, @Nullable AttributeSet attrs) {
        //初始化自定义属性
        initTypeArray(context, attrs);
        //想要重写onDraw,就要调用setWillNotDraw(false)
        //ViewGroup默认情况下,出于性能考虑,会被设置成WILL_NOT_DROW,这样,ondraw就不会被执行了。
        // 如果我们想重写一个viewgroup的ondraw方法,有两种方法:
        // 1,构造函数中,给viewgroup设置一个颜色。
        // 2,构造函数中,调用setWillNotDraw(false),去掉其WILL_NOT_DRAW flag。
        // 在viewgroup初始化的时候,它调用了一个私有方法:initViewGroup,它里面会有一句setFlags(WILLL_NOT_DRAW,DRAW_MASK);
        // 相当于调用了setWillNotDraw(true),所以说,对于ViewGroup,他就认为是透明的了,
        // 如果我们想要重写onDraw,就要调用setWillNotDraw(false)
        setWillNotDraw(false);

        initPaint();
        initXfermode();
        initRectF();
    }

    private void initPaint() {
        backGroundPaint = new Paint();
        backGroundPaint.setColor(backgroundColor);

        circlePaint = new Paint();
        circlePaint.setStyle(Paint.Style.FILL);
        circlePaint.setColor(bigCircleColor);
    }

    private void initXfermode() {
        //禁用硬件加速   https://www.jianshu.com/p/78c36742d50f
        //从硬件加速不支持的函数列表中,我们可以看到AvoidXfermode,PixelXorXfermode是完全不支持的,而PorterDuffXfermode是部分不支持的。
        //如果你的APP跑在API 14版本以后,而你洽好要用那些不支持硬件加速的函数要怎么办? 那就只好禁用硬件加速喽

        //该方法千万别放到onDraw()方法里面调用,否则会不停的重绘的,因为该方法调用了invalidate() 方法
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        mXfermode = new PorterDuffXfermode(PorterDuff.Mode.XOR);
    }

    private void initRectF() {
        backGroundRectF = new RectF();
        leftOval = new RectF();
        rightOval = new RectF();
    }

    private void initWidthAndHeight() {
        mWidth = getWidth();
        mHeight = getHeight();
    }

    private void initTypeArray(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomOypRoundLinearLayout);
        //个数
        smallCircleCount = typedArray.getInteger(R.styleable.CustomOypRoundLinearLayout_smallCircleCount,
                getResources().getInteger(R.integer.smallCircleCount));
        //尺寸
        circleStartY = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_circleStartY,
                getResources().getDimensionPixelOffset(R.dimen.circleStartY));
        smallCircleStartX = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_smallCircleStartX,
                getResources().getDimensionPixelOffset(R.dimen.smallCircleStartX));
        smallCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_smallCircleRadius,
                getResources().getDimensionPixelOffset(R.dimen.smallCircleRadius));
        bigCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_bigCircleRadius,
                getResources().getDimensionPixelOffset(R.dimen.bigCircleRadius));
        backgroundRadius = typedArray.getDimensionPixelOffset(R.styleable.CustomOypRoundLinearLayout_backgroundRadius,
                getResources().getDimensionPixelOffset(R.dimen.backgroundRadius));
        //颜色
        backgroundColor = typedArray.getColor(R.styleable.CustomOypRoundLinearLayout_backgroundColor,
                getResources().getColor(R.color.backgroundColor));
        smallCircleColor = typedArray.getColor(R.styleable.CustomOypRoundLinearLayout_smallCircleColor,
                getResources().getColor(R.color.smallCircleColor));
        bigCircleColor = typedArray.getColor(R.styleable.CustomOypRoundLinearLayout_bigCircleColor,
                getResources().getColor(R.color.bigCircleColor));
        //回收typedArray
        typedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //制成一个白色的圆角矩形  作为背景  画2个半圆 和 18个小圆  作为分隔线
        initWidthAndHeight();

        //使用离屏绘制  存为新图层
        int layerID = canvas.saveLayer(0, 0, mWidth, mHeight, backGroundPaint, Canvas.ALL_SAVE_FLAG);

        // 绘制目标图
        drawLeftAndRightBigHalfCircle(canvas);
        // 设置图层混合模式
        backGroundPaint.setXfermode(mXfermode);
        // 绘制源图
        drawBackGroundAndSmallCircle(canvas);
        // 清除混合模式
        backGroundPaint.setXfermode(null);
        // 恢复保存的图层;
        canvas.restoreToCount(layerID);
        // ==========================    第四步、 让RelativeLayout绘制自己
        super.onDraw(canvas);
    }

    private void drawBackGroundAndSmallCircle(Canvas canvas) {
        // ========================== 绘制白色矩形
        backGroundRectF.set(0, 0, mWidth, mHeight);
        canvas.drawRoundRect(backGroundRectF, backgroundRadius, backgroundRadius, backGroundPaint);

        // ==========================  绘制19个小圆  作为分隔线
        // 最后一个小圆和第一个小圆之间 有18段分隔空白
        smallCircleMargin = ((mWidth - smallCircleStartX) - (smallCircleStartX)) / (smallCircleCount - 1);
        circlePaint.setColor(smallCircleColor);
        for (int i = 0; i < smallCircleCount; i++) {
            canvas.drawCircle(smallCircleStartX + i * smallCircleMargin, circleStartY, smallCircleRadius, circlePaint);
        }
    }

    private void drawLeftAndRightBigHalfCircle(Canvas canvas) {
        // ========================== 绘制2个半圆
        leftOval.set(-bigCircleRadius, circleStartY - bigCircleRadius,
                bigCircleRadius, circleStartY + bigCircleRadius);
        /*
         * drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
         * oval :指定圆弧的外轮廓矩形区域。
         * startAngle: 圆弧起始角度,单位为度。
         * sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度,从右中间开始为零度。
         * useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。关键是这个变量,下面将会详细介绍。
         * paint: 绘制圆弧的画板属性,如颜色,是否填充等。
         */
        //左边的半圆
        canvas.drawArc(leftOval, -90, 180, true, circlePaint);

        //右边的半圆
        rightOval.set(mWidth - bigCircleRadius, circleStartY - bigCircleRadius,
                mWidth + bigCircleRadius, circleStartY + bigCircleRadius);
        canvas.drawArc(rightOval, 90, 180, true, circlePaint);
    }
}

继续查看下GPU的信息,如下所示
在这里插入图片描述

只绘制了一次,然后不再绘制,解决了这个性能问题。


作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:https://blog.csdn.net/qq446282412/article/details/88998767
☞ 本人QQ: 3024665621
☞ QQ交流群: 123133153
☞ github.com/ouyangpeng
[email protected]


发布了469 篇原创文章 · 获赞 1467 · 访问量 359万+

猜你喜欢

转载自blog.csdn.net/qq446282412/article/details/88998767