从图像URL加载图像需要很长时间才能显示

12

我使用了以下链接中的代码:Signare的博客。我有10个图像URL,并希望在我的屏幕上检索并显示它们。当我使用以上链接的代码时,加载所有图像需要超过10分钟的时间。如何加快加载速度?

URLBitmapField post_img= new URLBitmapField(image_url);
add(post_img);

其中类URLBitmapField 的定义如下:

import net.rim.device.api.math.Fixed32;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;

public class URLBitmapField extends BitmapField implements URLDataCallback {
    EncodedImage result = null;
    public static EncodedImage _encoded_img = null;
    int _imgWidth = 52;
    int _imgHeight = 62;
    int _imgMargin = 10;

    public URLBitmapField(String url) {
        try {
            http_image_data_extrator.getWebData(url, this);
        }
        catch (Exception e) {}
    }

    public Bitmap getBitmap() {
        if (_encoded_img == null) return null;
        return _encoded_img.getBitmap();
    }

    public void callback(final String data) {
        if (data.startsWith("Exception")) return;
        try {
            byte[] dataArray = data.getBytes();
            _encoded_img = EncodedImage.createEncodedImage(dataArray, 0, dataArray.length); // with scale
            _encoded_img = sizeImage(_encoded_img, _imgWidth, _imgHeight);
            setImage(_encoded_img);
            UiApplication.getUiApplication().getActiveScreen().invalidate();
        }
        catch (final Exception e){}
    }

    public EncodedImage sizeImage(EncodedImage image, int width, int height) {
        int currentWidthFixed32 = Fixed32.toFP(image.getWidth());
        int currentHeightFixed32 = Fixed32.toFP(image.getHeight());
        int requiredWidthFixed32 = Fixed32.toFP(width);
        int requiredHeightFixed32 = Fixed32.toFP(height);
        int scaleXFixed32 = Fixed32.div(currentWidthFixed32,requiredWidthFixed32);
        int scaleYFixed32 = Fixed32.div(currentHeightFixed32,requiredHeightFixed32);
        result = image.scaleImage32(scaleXFixed32, scaleYFixed32);
        return result;
    }
}

public interface URLDataCallback {
    public void callback(String data);
}

并且类 http_image_data_extractor 被定义为:

import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.system.WLANInfo;
import net.rim.device.api.ui.UiApplication;

public class http_image_data_extrator {
    static String url_="";
    static StringBuffer rawResponse=null;

    public static void getWebData(String url, final URLDataCallback callback) throws IOException {
        HttpConnection connection = null;
        InputStream inputStream = null;
        try {
            if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)&& RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) {
                url += ";interface=wifi";
            }
            connection = (HttpConnection) Connector.open(url, Connector.READ, true);
            String location=connection.getHeaderField("location");
            if(location!=null){
                if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)&& RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) {
                    location += ";interface=wifi";
                }
                connection = (HttpConnection) Connector.open(location, Connector.READ, true);
            }else{
                connection = (HttpConnection) Connector.open(url, Connector.READ, true);
            }

            inputStream = connection.openInputStream();
            byte[] responseData = new byte[10000];
            int length = 0;
            rawResponse = new StringBuffer();
            while (-1 != (length = inputStream.read(responseData))) {
                rawResponse.append(new String(responseData, 0, length));
            }
            int responseCode = connection.getResponseCode();
            if (responseCode != HttpConnection.HTTP_OK){
                throw new IOException("HTTP response code: "+ responseCode);
            }

            final String  result = rawResponse.toString();
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run(){
                    callback.callback(result);
                }
            });
        }
        catch (final Exception ex) {
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    callback.callback("Exception (" + ex.getClass() + "): " + ex.getMessage());
                }
            });
        }
    }
}  

1
如果您想在BlackBerry屏幕上显示位图图像,可以查看此链接点击这里,您将在BlackBerry RssFeed Reader中找到一个示例。 - String
我尝试了,但是花费了太多时间... - Rince Thomas
3
请解释一下为什么需要这么大的图片?因为没有任何分辨率与其相同的Java BB。因此,网络速度很慢且图像很大,同时重新调整大小需要一些时间,String.getBytes()也将生成新数组——更多的内存和时间。默认下载类型是DirectTCP,如果没有WiFi可能会受到限制。 - Eugen Martynov
5
如果您想下载大文件,那么需要花费较长时间。在下载之前,您需要在服务器端进行一些操作。 - Rupak
2
你创建了一个新的字符串,只是为了将其内容附加到缓冲区中,然后就被丢弃了。其中一种优化方法是将所有数据读入 ByteArrayOutputStream 中,然后一次性转换为图像。如果在垃圾回收中浪费了一些时间,这将有所帮助。 - Audrius Meškauskas
显示剩余10条评论
1个回答

1

在服务器上调整大小

在服务器上调整图像大小是最好的选择。因为下载大图像并将其缩小需要设备上的大量资源(网络、内存、CPU)。

通过代理调整大小

如果图像服务器不在您的控制范围内,您仍然可以使用自己的服务器作为调整大小的代理(将图像URL和所需大小发送到您的服务器,它获取图像,调整大小并返回调整后的图像)。也许已经有这样的服务了。

更便宜的解码选项

一些解码选项可能会使解码(和调整大小)更加便宜。DECODE_NO_DITHER、DECODE_READONLY和DECODE_NATIVE都值得尝试。
http://www.blackberry.com/developers/docs/4.2api/net/rim/device/api/system/EncodedImage.html#DECODE_NO_DITHER

串行而非并行

你提到正在加载10张图片。如果加载这10张图片的时间比单独加载1张图片的时间多出了10倍,那么系统可能会出现“抖动”现象。就像它可能会启动所有10个请求,然后在回调函数中一次性处理10个全尺寸图片。可以尝试在开始下载下一个图片之前显示第一张图片,这也可以让用户更快地看到东西。同样,在回调函数中同时调用10次invalidate可能会引起卡顿。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接