canvas.clipRect操作在android6上绘图正常但在android9不正常的原因

编者:李国帅

qq:9611153 微信lgs9611153

时间 2020/6/17

背景原因:

android绘图的方法有很多种,比如opengl,sdl, canvas,surfaceview canvas等,不过对于简单绘图功能,使用canvas就足够了。

 

几天前,遇到了一个问题,以前在android6.0设备上能够正常绘图的程序在android9.0手机上突然就不行了。

解决这个问题的过程中依次排除了函数兼容性错误,硬件加速等错误,最后才锁定问题。

 

所需资源:

Android,canvas绘图

 

解决过程:

首先修改了明显的语法错误:

   if(Build.VERSION.SDK_INT >= 26){

        m_memCanvas.clipRect(left, top, right, bottom);

    }else {

        m_memCanvas.clipRect(left, top, right, bottom, Region.Op.UNION);

    }

Canvas.clipRect:在手机屏幕上裁剪出一块区域来,起点是从屏幕的左上角开始。

更改了也没有效果,说明这不是简单的兼容性问题。

 

然后,发现还是有问题,图像显示不正常。

查了网上的资料,有人说是硬件加速的问题,于是添加了相关语句。

        this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);//禁止硬件加速 sdk 29

还有其他禁止硬件加速的方法,都试了,依然如故,说明还是没有找对方法。

禁止加速不行,那就是其他原因。

 

也不是canvas函数不起作用,因为新编写的例子都是正常的。

 

仔细观察,发现canvas执行drawPath的时候是能够显示一个小区域。所以可能是与clipRect函数有关。

于是打印出clipRect的区域和path中lineto画线的区域,一切都是正常对应的,不存在绘制到无效区域的情况

 

到底是为什么呢?

仔细观察对比正常绘图与不正常绘图,发现当前代码中,每次进行裁剪之前进行了canvas.save();但是在绘图之后却没有调用restore()。

是这个原因吗?

 

save() : 用来保存Canvas的状态,save()方法之后的代码,可以调用Canvas的平移、放缩、旋转、裁剪等操作!

 

restore():用来恢复Canvas之前保存的状态(可以想成是保存坐标轴的状态),防止save()方法代码之后对Canvas执行的操作,继续对后续的绘制会产生影响,通过该方法可以避免连带的影响

 

通过测试,在加入restore()之后,发现在android 9上面依然是可以显示绘图的

 

正确的做法:

 

使用裁剪clip绘图的流程必须是:

 canvas.save()----canvas.clipRect----canvas.draw--- canvas.restore();

整个流程一个步骤都不能少。

canvas.save();

canvas.clipRect(object_x, object_y, object_x + object_width, object_y + object_height);

canvas.drawBitmap(boosPlaneBomb, object_x, object_y - y, paint);

canvas.restore();

 

正确的流程才能保证正常的功能和愿景。

总结:

说到底,这依然是个兼容性问题。

对于老版本的android sdk,如果没有调用canvas.restore()直接调用canvas.clipRect会使用新的裁剪区域,但是新版本不行。

 

所谓的一朝天子一朝臣,不同的SDK版本采用不同规范(语言的,业务的),排除方式。

当系统或者底层sdk发生变化的时候,可能会引起依赖于他们的上层软件发生相应的变化

这就是为什么以前的软件用得好好的,升级之后突然就不行了的原因。

 

32位计算机的时候,16位程序不能用了;系统升级后,许多系统工具不能用了。语言升级后,许多代码不能用了。

不要老是想后看,世界总是滚滚向前。

 

语言升级问题

语言也是不断的发展,严谨程度,开发效率,易用程度都在变化。

语言开发包原来的语法,用法可能不严谨,不规范。语言升级后,基于此的代码也可能出现兼容性问题。

 

如在VC6中

for(int i=0;i<10;i++);

for(i=0;i<10;i++);

是正确的的,可以编译的,但是在新版本VC中则是错误的。这个问题编译过directshow源码的朋友应该很清楚。

 

那些成熟的应用广泛的sdk错误很少,但是并不代表没有错误,而且随着sdk的更新发展,以及所有规范的变迁,都在不停的完善。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微澜-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值