12

次のリンクのコードを使用しました: Signare's Blog。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_extratorは次のように定義されます。

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());
                }
            });
        }
    }
}  
4

1 に答える 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 個のフルスケール イメージを同時に処理するようになります。次のダウンロードを開始する前に最初の画像を表示することもできます。これにより、ユーザーはすぐに何かを見ることができます。同様に、(コールバックで)invalidate を 10 回並行して呼び出すと、問題が発生する可能性があります。

于 2013-02-24T20:15:57.147 に答える