对比图片解析速度
对于素材在 100k 以下的帧动画,上一篇的逐帧解析方案完全能够胜任。但如果素材是几百k,时间性能就不如预期。
掘友“小前锋”问:“你的方案有测试过大图吗?比如1024*768px”
在逐帧解析SurfaceView上试了下这个大小的帧动画,虽然播放过程很连续,但 600ms 的帧动画被放成了 1s。因为预定义的每帧播放时间被解码时间拉长了。
有没有比BitmapFactory.decodeResource()
更快的解码方式?
于是乎对比了各种图片解码的速度,其中包括BitmapFactory.decodeStream()
、BitmapFactory.decodeResource()
、并分别将图片放到res/raw
、res/drawable
、及assets
,还在 GitHub 上发现了RapidDecoder
这个库(兴奋不已!)。自定义了测量函数执行时间的工具类:
public class MethodUtil {
//测量并打印单次函数执行耗时
public static long time(Runnable runnable) {
long start = SystemClock.elapsedRealtime();
runnable.run();
long end = SystemClock.elapsedRealtime();
long span = end - start;
Log.v(“ttaylor”, “MethodUtil.time()” + " time span = " + span + " ms");
return span;
}
}
public class NumberUtil {
private static long total;
private static int times;
private static String tag;
//统计并打印多次执行时间的平均值
public static void average(String tag, Long l) {
if (!TextUtils.isEmpty(tag) && !tag.equals(NumberUtil.tag)) {
reset();
NumberUtil.tag = tag;
}
times++;
total += l;
int average = total / times ;
Log.v(“ttaylor”, "Average.average() " + NumberUtil.tag + " average = " + average);
}
private static void reset() {
total = 0;
times = 0;
}
}
经多次测试取平均值,执行时间最长的是BitmapFactory.decodeResource()
,最短的是用BitmapFactory.decodeStream()
解析assets
图片,后者只用了前者一半时间。而RapidDecoder
库的时间介于两者之间(失望至极~),不过它提供了一种边解码边绘制的技术号称比先解码再绘制要快,还没来得及试。
虽然将解码时间减半了,但解码一张 1MB 图片还是需要 60+ms,仍不能满足时间性能要求。
独立解码线程
现在的矛盾是 图片解析速度 慢于 图片绘制速度,如果解码和绘制在同一个线程串行的进行,那解码势必会拖慢绘制效率。
可不可以将解码图片放在一个单独的线程中进行?
在上一篇FrameSurfaceView
的基础上新增了独立解码线程:
public class FrameSurfaceView extends BaseSurfaceView {
…
//独立解码线程
private HandlerThread decodeThread;
//解码算法写在这里面
private DecodeRunnable decodeRunnable;
//播放帧动画时启动解码线程
public void start() {
decodeThread = new HandlerThread(DECODE_THREAD_NAME);
decodeThread.start();
handler = new Handler(decodeThread.getLooper());
handler.post(decodeRunnable);
}
private class DecodeRunnable implements Runnable {