2

私はJ2MEに存在する概念にそれほど慣れていませんが、私はすべきではない方法で一種の怠惰です:最近、私のアプリは画像をキャンディーとしてメモリにロードしています...

Sprite example = new Sprite(Image.createImage("/images/example.png"), w, h);

それが最善の方法かどうかはわかりませんが、Motorola Z6では、昨夜、古いSamsungの携帯電話でアプリをテストしたところ、画像が読み込まれず、スレッドを開始するために何度か試行する必要がありました。現れます。画面が白のままだったので、画像の読み込みがうまくいかないことに気づきました...アプリで読み込みルーチンを正しく作成する方法を教えてくれる人はいますか?

4

3 に答える 3

4

何を探しているのか正確にはわかりませんが、説明する動作は、OutOfMemory例外が発生しているように聞こえます。画像のサイズを小さくして(ヒープの使用量はサイズに基づいています)、動作が停止するかどうかを確認してください。これにより、それが本当にOutOfMemoryの問題なのか他の問題なのかがわかります。

その他のヒント:

  1. 画像を最大から最小にロードします。これはヒープの断片化に役立ち、最大の画像に対して最大のヒープスペースを可能にします。
  2. ロードした方法と逆の順序でアンロード(nullに設定)し、実行後にガベージコレクションを実行します。GCを呼び出した後は、必ずThread.yield()を実行してください。
  3. 必要な画像のみをロードするようにしてください。アプリケーションが存在しない状態からイメージをアンロードします。
  4. スプライトを作成しているため、1つの画像に複数のスプライトがある場合があります。イメージプールを作成して、イメージを1回だけロードするようにすることを検討してください。次に、各Spriteオブジェクトを、必要なプール内の画像にポイントします。あなたの質問の例は、同じ画像をメモリに複数回ロードする可能性が高いようです。これは無駄であり、OutOfMemoryの問題の一部である可能性があります。
于 2009-05-28T21:06:03.947 に答える
1

フィルム画像(1つの画像に定義された寸法の画像のセット)を使用し、ロジックを使用して一度に1つずつ引き出します。

これらは1つの画像にグループ化されているため、画像ごとのヘッダースペースを節約でき、使用するメモリを削減できます。

この手法は、MIDP1.0のメモリに制約のあるデバイスで最初に使用されました。

于 2009-06-04T10:52:39.983 に答える
0

画像を何度も読み込まないというFostahのアプローチを使用して、次のクラスを作成しました。

public class ImageLoader {
    private static Hashtable pool = new Hashtable();

    public static Image getSprite(String source){
        if(pool.get(source) != null) return (Image) pool.get(source);
        try {
            Image temp = Image.createImage(source);
            pool.put(source, temp);
            return temp;
        } catch (IOException e){
            System.err.println("Error al cargar la imagen en "+source+": "+e.getMessage());
        }
        return null;
    }
}

したがって、画像が必要なときはいつでも、最初にプールに画像を要求するか、プールにロードします。

于 2009-05-29T00:14:27.450 に答える