Android性能优化 _ 大图做帧动画卡?优化帧动画之 SurfaceView滑动窗口式帧复用

本文介绍了如何优化Android帧动画的性能,通过SurfaceView逐帧解析与帧复用,使用独立解码线程提高效率。对比了不同图片解码速度,并实现了滑动窗口机制与预解析,以减少内存压力。最后,讨论了复用队列以解决内存中过多Bitmap对象的问题。
摘要由CSDN通过智能技术生成

(ps:粗斜体表示引导方案逐步进化的关键点)

SurfaceView逐帧解析 & 帧复用

简单回顾下上一篇的内容:原生帧动画在播放前解析所有帧,对内存压力大。SurfaceView可以精细地控制帧动画每一帧的绘制,在每一帧绘制前才解析当前帧,且解析后续帧时复用前帧内存空间。遂整个过程在内存只申请了一帧图片大小的空间。下面罗列了一些关键代码:

基类:定义绘制框架
public abstract class BaseSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

//绘制线程
private HandlerThread handlerThread;
private Handler handler;

@Override
public void surfaceCreated(SurfaceHolder holder) {
startDrawThread();
}

private void startDrawThread() {
handlerThread = new HandlerThread(“SurfaceViewThread”);
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
handler.post(new DrawRunnable());
}

private class DrawRunnable implements Runnable {
@Override
public void run() {
try {
canvas = getHolder().lockCanvas();
//绘制一帧,包括解码+绘制帧
onFrameDraw(canvas);
} catch (Exception e) {
e.printStackTrace();
} finally {
getHolder().unlockCanvasAndPost(canvas);
onFrameDrawFinish();
}
//若onFrameDraw()执行超时,会导致下一帧的绘制被推后,预定的帧时间间隔不生效
handler.postDelayed(this, frameDuration);
}
}

protected abstract void onFrameDraw(Canvas canvas);
}

//帧动画绘制类:将绘制内容具体化为一张Bitmap
public class FrameSurfaceView extends BaseSurfaceView {

private BitmapFactory.Options options;

@Override
protected void onFrameDraw(Canvas canvas) {
clearCanvas(canvas);
if (!isStart()) {
return;
}
if (!isFinish()) {
//绘制一帧
drawOneFrame(canvas);
} else {
onFrameAnimationEnd();
}
}

private void drawOneFrame(Canvas canvas) {
//解析帧
frameBitmap = BitmapFactory.decodeResource(getResources(), bitmaps.get(bitmapIndex), options);
//复用帧
options.inBitmap = frameBitmap;
//绘制帧
canvas.drawBitmap(frameBitmap, srcRect, dstRect, pa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值