Android 仿应用宝下载进度条-性能测试与进度绘制修改

一件开心的事:

哈哈哈,先容我高兴一会。就在昨天,当我打开csdn博客的时候,发现了一件让我激动了半天的事,就是那个男人竟然关注了我,关注了我,关注了我。有图有真相:
关注

这感觉无法言表,不说了,我去敲几行代码掩饰一下内心的喜悦。


对于FlickerProgressBar请看:

Android 仿应用宝下载进度条

1.问题描述

1.1提出问题

在FlickerProgressBar实现过程中对于进度的相关绘制有同学提出了疑问@王少星,就是绘制进度的时候都需要调用Bitmap.createBitmap()来重新创建进度bitmap,是否有更好的方法去处理?首先感谢该同学的提问。这个问题在开发过程中我也意识到了,不过当时没有想到其他更好的方法,只想着先实现效果。

1.2问题所在

最开始进度绘制是这样的

private void drawProgress() {
    bgPaint.setStyle(Paint.Style.FILL);
    bgPaint.setStrokeWidth(0);
    bgPaint.setColor(progressColor);

    float right = (progress / MAX_PROGRESS) * getMeasuredWidth();
    pgBitmap = Bitmap.createBitmap((int) Math.max(right, 1), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    pgCanvas = new Canvas(pgBitmap);
    pgCanvas.drawColor(progressColor);

    if(!isStop){
        bgPaint.setXfermode(xfermode);
        pgCanvas.drawBitmap(flikerBitmap, flickerLeft, 0, bgPaint);
        bgPaint.setXfermode(null);
    }
}

可以看到每次都根据当前进度创建了一个新的bitmap,pgBitmap = Bitmap.createBitmap((int) Math.max(right, 1), getMeasuredHeight(), Bitmap.Config.ARGB_8888);,先不说这样做有什么不好,来看看下面这幅图

性能测试图1

可以看到在下载过程中,也就是进度条绘制过程中,内存分配图成锯齿形。然后再看数据统计
Free[1.28 MB]
Allocated[31.03 MB]

这里出现了明显的内存占用过大和内存抖动问题。

2.问题解决

2.1方法一

首先需要明白一点是这里需要创建一个bitmap,和滑块bitmap进行SRC_ATOP模式绘制。
然后,这里的绘制进度需要一个根据当前进度计算的宽度创建的一个bitmap,那么突破口就是bitmap和宽度。

查看Bitmap的方法,找到了两个可以修改宽度的方法,一个是
setWidth (int width),另一个是
reconfigure (int width, int height, Bitmap.Config config)
setWidth()方法在内部调用的也是reconfigure()方法。

修改:
pgBitmap只用在init()方法中初始化一次
pgBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);

注意:
- setWidth和reconfigure方法中的宽度参数不能大于创建时bitmap的宽度,不然会抛异常。
宽高均为控件宽高,而不是光满足大于0的某一个值,不然调用reconfigure 和 setWidth抛异常Bitmap not large enough to support new configuration

  • 这两个方法在api19才加进来的,所以对于低版本的支持不是很好

方法一修改进度绘制方法:

@TargetApi(Build.VERSION_CODES.KITKAT)
    private void drawProgress() {
        bgPaint.setStyle(Paint.Style.FILL);
        bgPaint.setStrokeWidth(0);
        bgPaint.setColor(progressColor);

        float right = (progress / MAX_PROGRESS) * getMeasuredWidth();
        pgBitmap.setWidth((int) Math.max(1, right));
       //pgBitmap.reconfigure((int) Math.max(right, 1), getMeasuredHeight(), Bitmap.Config.ARGB_8888);

        pgCanvas = new Canvas(pgBitmap);
        pgCanvas.drawColor(progressColor);


        if(!isStop){
            bgPaint.setXfermode(xfermode);
            pgCanvas.drawBitmap(flikerBitmap, flickerLeft, 0, bgPaint);
            bgPaint.setXfermode(null);
        }
    }

2.2 方法二

方法一能很好的解决上面提到的问题,但是对于低版本支持不是很好。所以需要寻找更好的方法。

最后,问题的解决根本再一次落到了canvas的clipRect方法。让我深深的感受到这个方法的强大。

思路:在初始化方法中就创建pgBitmap,并且宽高为控件宽高,并初始化pgCanvas。
在绘制进度的时候在调用pgCanvas的clipRect方法,然后在截取的宽度中进行相关绘制。这样可以很好的解决问题了,也不用考虑bitmap的create方法中宽高必须大于0和抛异常了。

初始化方法


private void init() {
    bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    textPaint.setTextSize(textSize);
    textBouds = new Rect();

    progressColor = loadingColor;
    flikerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flicker);
    flickerLeft = -flikerBitmap.getWidth();

//这里就进行初始化,只用创建一次就可以了
    pgBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    pgCanvas = new Canvas(pgBitmap);

    thread = new Thread(this);
    thread.start();
}

方法二修改进度绘制方法:


private void drawProgress() {
        bgPaint.setStyle(Paint.Style.FILL);
        bgPaint.setStrokeWidth(0);
        bgPaint.setColor(progressColor);

        float right = (progress / MAX_PROGRESS) * getMeasuredWidth();
        pgCanvas.save(Canvas.CLIP_SAVE_FLAG);
        pgCanvas.clipRect(0, 0, right, getMeasuredHeight());
        pgCanvas.drawColor(progressColor);
        pgCanvas.restore();

        if(!isStop){
            bgPaint.setXfermode(xfermode);
            pgCanvas.drawBitmap(flikerBitmap, flickerLeft, 0, bgPaint);
            bgPaint.setXfermode(null);
        }
    }

3.修改后性能

修改后性能效果图

对比修改前的,效果对比很明显。
这里内存分配非常平稳,没有丝毫抖动。再看看数据:
Free[8.37 MB]
Allocated[19.52 MB]

分配内存减少约10M,空闲内存提高约6.5M。cpu占用区别不是很明显。

4.下载

下载:https://github.com/LineChen/FlickerProgressBar

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值