Glide版本3.7 目前不清楚4及以上版本是否有同样的问题
今天使用glide播放gif发现播放的速度很慢,在ios或者其他地方都没有这种问题。
跟踪源码查找发现,与播放速度相关的是每一帧的延时时间:
private void loadNextFrame() {
if (!isRunning || isLoadPending) {
return;
}
isLoadPending = true;
gifDecoder.advance();
long targetTime = SystemClock.uptimeMillis() + gifDecoder.getNextDelay();//获取一帧的延时时间
DelayTarget next = new DelayTarget(handler, gifDecoder.getCurrentFrameIndex(), targetTime);
requestBuilder
.signature(new FrameSignature())
.into(next);
}
public int getDelay(int n) {
int delay = -1;
if ((n >= 0) && (n < header.frameCount)) {
delay = header.frames.get(n).delay;//从解析出的gifheader中获取此帧延时时间
}
return delay;
}
而在解析gif的过程中:
int delayInHundredthsOfASecond = readShort();
// TODO: consider allowing -1 to indicate show forever.
if (delayInHundredthsOfASecond < MIN_FRAME_DELAY) { //这个值为3
delayInHundredthsOfASecond = DEFAULT_FRAME_DELAY;//这个值为10
}
header.currentFrame.delay = delayInHundredthsOfASecond * 10;
当解析每帧数据时,如果此帧延时<30毫秒,则会被赋值为100毫秒。debug发现ui小哥哥给我的gif正好是20毫秒每帧延迟,所以播放很慢。这就尴尬了。
因为不太想下载源码修改,这里偷懒直接用了反射去修改。
Glide.with(this)
.load(lotteryBean.getBanner_pic())
.asGif()
.into(new SimpleTarget<GifDrawable>(){
@Override
public void onResourceReady(GifDrawable resource, GlideAnimation<? super GifDrawable> glideAnimation) {
try {
Field field = GifDecoder.class.getDeclaredField("header");
field.setAccessible(true);
GifHeader header = (GifHeader) field.get(resource.getDecoder());
Field field2 = GifHeader.class.getDeclaredField("frames");
field2.setAccessible(true);
List frames = (List) field2.get(header);
if (frames.size()>0){
Field delay = frames.get(0).getClass().getDeclaredField("delay");
delay.setAccessible(true);
for (Object frame : frames) {
delay.set(frame,20);//这里直接给修改成了20
}
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
mBannerImage.setImageDrawable(resource);
resource.setLoopCount(Integer.MAX_VALUE);
resource.start();
}
});
不过这种方式不太灵活,只能算是应急吧。尝试了反射替换decoder相关类,感觉比较麻烦,Glide的很多类都无法在包外调用,暂时不了了之TT。
欢迎有好的方案的老哥留言~