Java中的双缓存技术
(2014-04-16 13:32:02)
标签:
it |
分类: Java/Android |
已经停滞在双缓存显示图片这一段时间了,因为代码运行出现了意外,一直想寻求解决的办法,最终找到的方法让我对这个技术颇感到失望。
首先描述下问题,先看下面一段代码:
//双缓存应用
import java.applet.Applet;
import java.awt.*;
import java.awt.Graphics;
import java.awt.Image;
public class Media extends Applet {
}
采用双缓存技术的标准流程一般如下:
首先需要两个对象变量,一个是Image对象(这个例子中变量名为buffer),一个是Graphics对象(这个例子中变量名为gContext),然后用下列两个语句俩创建图形双缓存:
buffer = createImage( int width, int height);
gContext = buffer.getGraphics();
第一个语句是创建大小为width*height的图像,这也就是在动画中需要显示的图片大小,第二语句则是获取Image对象对应的绘图的环境的。第二句没有问题,问题就出现在第一句上,显示动画的时候,如果并不知道需要显示图片的大小呢?看到有推荐使用如下语句的:
buffer = createImage( picture.getWidth(), picture.getHeight() );
其中picture是Image的对象,就是需要显示的图片对象,但是这样带来一个问题,就算在之前运行了
picture = getImage( getDocumentBase(), ImageLocation );
这样的语句,再运行前面所述语句,其返回的宽度和高度的数值依旧是-1,查询API后发现,返回-1的数值说明,图片没有完全的加载,那么这样很快就会有一个问题,就是图片神马时候才加载完成,看到相关的资料显示,Java的图片加载和绘制是一个异步的过程,貌似在图片draw的时候才会加载,至于加载完成,天知道?
那么就没有解决办法了吗?解决办法还是有的,Java在图片加载中提供了一个MediaTracket类,可以用来监视图片的加载,用MediaTracket的对象调用waitforID( int ID )的方法就可以监视编号为ID的图片加载完成,其主要步骤如下:
MediaTraker ImageMediaTraker; //新建MediaTraker对象
//创建对象,并指定o为图片需要绘制的对象(一般用this)
ImageMediaTraker = new
//在加载图片的后面附上语句
ImageMediaTraker.addImage(image picture, int ID );
//指定等待对应ID图片加载完毕
ImageMediaTraker.waitForID( int ID);
运用上述技术,就可以保证图片在自己需要的时候加载完毕了,但是这样有一个小问题,就是由于buffer在createImage后就保持大小不变了,一旦动画显示的图片的大小规格不是一样的,那么后续过程会出现图片显示不完全的现象,虽然这样的例子在真正显示动画的时候很少,但是我做测试的时候还是遇到了,解决的办法是神马呢,那就是在每次显示了buffer图片后,重新用buffer调用一次createImage方法,并让Graphics对象重新获取一次绘图环境,也就是重新运行下列语句
buffer = createImage( int width, int height);
gContext = buffer.getGraphics();
上述这个小问题是我自己纠结了,一般动画显示的图片大小是一致的,但是看到有给出的示例,createImage中使用的长宽是就是applet或者是对话框的大小的,这个问题就凸显了,其实将createImage中使用对话框大小的貌似占大多数,那么为了确保图片的显示正确那么,必须每次加载了缓存后,重新创建缓存大小,或者接收对话框变化的通知后,重建缓存大小,或者保持绘图的大小区域一直不变,这样才能确保显示正确。
但是需要注意的是,createImage中使用对话框的大小,并且是使用初始化的时候对话框的大小(不使用固定对话框大小铁定会发生问题),显示图片也会出现问题,因为无法做到适配显示,所以可能会出现图片显示只出现一部分的情况,这说明图片无法适配显示高度,也就是无法做到等比例显示,那么这个时候还得想别的方法。
啰嗦了一大堆,就是想说明两个问题,使用双缓存,缓存大小选取要谨慎;Java图片加载与显示是异步的,其图片加载完成,可能是在显示的时候,如需显示之前就加载完毕,需要一个MediaTracker的监视器来监视。
双缓存技术看似很容易,用起来却有些麻烦,大家且用且珍惜。