0

を呼び出す画面がありますlistfield

public class Main_AllLatestNews extends MainScreen {
private Database_Webservice webservice;
private String[] title, category, date, imagepath = {"no picture", "no picture", "no picture", "no picture","no picture","no picture","no picture","no picture","no picture", "no picture"};
private int[] newsid;
private List_News newslist;

public Main_AllLatestNews(final boolean needdownload) {
    super(USE_ALL_WIDTH);
    webservice = new Database_Webservice();
    add(new Custom_TopField(this, 0, -1, "", 1, 1));
    add(new Custom_BottomField(this, 0));
    add(new Custom_HeaderField(Config_GlobalFunction.latest));
    if (needdownload){
        Main.getUiApplication().pushScreen(
                new Custom_LoadingScreen(30));
        webservice.UpdateAllCatNews();          
    }else {
        webservice.LoadtodayNews(); 
        newsid = new int[webservice.news.size()];
        title = new String[webservice.news.size()];
        category = new String[webservice.news.size()];
        date = new String[webservice.news.size()];
        //imagepath = new String[webservice.news.size()];

        for (int i = 0; i < webservice.news.size(); i++) {
            newslist = (List_News) webservice.news.elementAt(i);
            newsid[i] = newslist.getID();
            title[i] = newslist.getNtitle();
            category[i] = newslist.getNewCatName();
            date[i] = newslist.getNArticalD();
            //imagepath[i] = newslist.getImagePath();
        }
        add(new Custom_ListField(newsid, title, date, category, imagepath, true));
    }
}
}

追加するとcustom_listfield、次のようになります。

タイマー 0 の割り当てに失敗しました: スロットが残っていません

これが私のlistfield

public Custom_ListField(int newsid[], String title[], String date[],
        String category[], String imagepath[], boolean islatest) {
    super(0, ListField.MULTI_SELECT);
    this.newsid = newsid;
    setCallback(this);
    setBackground(Config_GlobalFunction.loadbackground("background.png"));
    this.islatest = islatest;
    rows = new Vector();

    for (int x = 0; x < title.length; x++) {
        TableRowManager row = new TableRowManager();

        titlelabel = new Custom_LabelField(title[x],
                LabelField.USE_ALL_WIDTH | DrawStyle.LEFT);
        titlelabel.setFont(Font.getDefault().derive(Font.BOLD, 23));
        row.add(titlelabel);

        datelabel = new Custom_LabelField(date[x], DrawStyle.ELLIPSIS
                | LabelField.USE_ALL_WIDTH | DrawStyle.LEFT);
        datelabel.setFont(Font.getDefault().derive(Font.BOLD, 18));
        datelabel.setFontColor(Color.GRAY);
        row.add(datelabel);

        categorylabel = new Custom_LabelField(category[x],
                DrawStyle.ELLIPSIS | LabelField.USE_ALL_WIDTH
                        | DrawStyle.LEFT);
        categorylabel.setFont(Font.getDefault().derive(Font.BOLD, 18));
        categorylabel.setFontColor(Color.RED);
        row.add(categorylabel);

        /*Bitmap imagebitmap = null;
        if (!imagepath[x].toString().equals("no picture")) {
            imagebitmap = Util_ImageLoader.loadImage(imagepath[x]);
        } else {
            imagepath[x] = "image_base.png";
            imagebitmap = Bitmap.getBitmapResource(imagepath[x]);
        }
        image = new BitmapField(imagebitmap, Field.FIELD_HCENTER
                | Field.FIELD_VCENTER);
        row.add(image);*/

        //setRowHeight(image.getBitmapHeight() + 10);
        setRowHeight(70);
        rows.addElement(row);
    }
    setSize(rows.size());
}

このリストでは、10 個以上の画像を呼び出します。最初にリンクが送信されたことを確認し、それ以外の場合はローカル画像を読み込みます。したがって、行の高さは同じである必要はありませんが、各行の行の高さを自動設定するのではなく、すべての行に同じ高さを設定します。呼び出す画像が多すぎるため、メモリが不足していると思いますか? しかし、私はアンドロイドでも問題ありません。

これは私のimageloaderです。

public class Util_ImageLoader {

public static Bitmap loadImage(String url) {
    HttpConnection connection = null;
    InputStream inputStream = null;
    EncodedImage bitmap;
    byte[] dataArray = null;

    try {
        // can use this for BlackBerry 5.0+ :
        // connection = (HttpConnection) (new
        // ConnectionFactory()).getConnection(url).getConnection();
        connection = (HttpConnection) Connector
                .open(url + Util_GetInternet.getConnParam(),
                        Connector.READ, true);
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpConnection.HTTP_OK) {
            inputStream = connection.openDataInputStream();
            dataArray = IOUtilities.streamToBytes(inputStream);
        }
    } catch (Exception ex) {
    } finally {
        try {
            inputStream.close();
            connection.close();
        } catch (Exception e) {
        }
    }

    if (dataArray != null) {
        bitmap = EncodedImage.createEncodedImage(dataArray, 0,
                dataArray.length);
        return bitmap.getBitmap();
    } else {
        return null;
    }
}
}

1) メモリの使用を減らすために何ができますか?

2) 異なる行の高さを設定するには? 私は設定されbitmap.getbitmapheight()ていますが、異なるビットマップは異なる高さになります。

//更新しました//

シミュレーター 9930 OS 7.0 および 8520 OS 5.0 で実行しています。どちらも同じ結果です。キーに署名した後も警告メッセージが表示されるため、実デバイスは実行できませんtry to Secure APi。私はすべての画像も同じように完全にコメントしています。オンラインにもローカルにもイメージを呼びませんでした。データの問題だと思いますか?

@AlanLai、これが実行されているデバイスとOSを教えてください。それはシミュレータですか、それとも実際のハードウェアですか? 画像を完全にコメントアウトしてみてください。画像 (ネットワーク画像またはローカル画像) を表示しません。それでも問題が発生するかどうかを確認してください。問題の原因となっているコードが正確にどこにあるかを絞り込んでみましょう。注: ここでのコメントへの回答としてではなく、上記の質問でテストしているデバイスに関する情報を投稿してください。ありがとう

4

3 に答える 3

0

問題はでしたCustom_ListField。これはextends listfield カスタムの代わりにすべきですextends manager

public class Custom_ListField extends ListField {
private String[] title, category, date, imagepath;
private int[] newsid, catsid;
private List_News newslist;
private Bitmap imagebitmap[], localimage = Bitmap
        .getBitmapResource("image_base.png");
private BrowserField webpage;
private Custom_BrowserFieldListener listener;
private boolean islatest;

private Vector content = null;
private ListCallback callback = null;

private int currentPosition = 0;

public Custom_ListField(Vector content, boolean islatest) {
    this.content = content;
    this.islatest = islatest;
    newsid = new int[content.size()];
    title = new String[content.size()];
    category = new String[content.size()];
    date = new String[content.size()];
    imagepath = new String[content.size()];
    catsid = new int[content.size()];
    imagebitmap = new Bitmap[content.size()];

    for (int i = 0; i < content.size(); i++) {
        newslist = (List_News) content.elementAt(i);
        newsid[i] = newslist.getID();
        title[i] = newslist.getNtitle();
        category[i] = newslist.getNewCatName();
        date[i] = newslist.getNArticalD();
        imagepath[i] = newslist.getImagePath();

        if (!imagepath[i].toString().equals("no picture")) {
            imagebitmap[i] = Util_ImageLoader.loadImage(imagepath[i]);
        } else {
            imagebitmap[i] = localimage;
        }
        catsid[i] = newslist.getCatID();
    }

    initCallbackListening();
    this.setRowHeight(localimage.getHeight() + 10);
}

private void initCallbackListening() {
    callback = new ListCallback();
    this.setCallback(callback);
}

private class ListCallback implements ListFieldCallback {

    public ListCallback() {
        setBackground(Config_GlobalFunction
                .loadbackground("background.png"));
    }

    public void drawListRow(ListField listField, Graphics graphics,
            int index, int y, int width) {
        currentPosition = index;
        graphics.drawBitmap(
                Display.getWidth() - imagebitmap[index].getWidth() - 5,
                y + 3, imagebitmap[index].getWidth(),
                imagebitmap[index].getHeight(), imagebitmap[index], 0, 0);
        graphics.setColor(Color.WHITE);
        graphics.drawRect(0, y, width, imagebitmap[index].getHeight() + 10);



        graphics.setColor(Color.BLACK);
        graphics.setFont(Font.getDefault().derive(Font.BOLD, 20));
        graphics.drawText(title[index], 5, y + 3, 0, Display.getWidth()
                - imagebitmap[index].getWidth() - 10);

        System.out.println(Display.getWidth()
                - imagebitmap[index].getWidth() - 10);

        graphics.setColor(Color.GRAY);
        graphics.setFont(Font.getDefault().derive(Font.BOLD, 15));
        graphics.drawText(date[index], 5, y + 6
                + Font.getDefault().getHeight() + 3);

        if (islatest) {
            graphics.setColor(Color.RED);
            graphics.setFont(Font.getDefault().derive(Font.BOLD, 15));
            graphics.drawText(category[index], Font.getDefault()
                    .getAdvance(date[index]) + 3, y + 6
                    + Font.getDefault().getHeight() + 3);
        }
    }

    public Object get(ListField listField, int index) {
        return content.elementAt(index);
    }

    public int getPreferredWidth(ListField listField) {
        return Display.getWidth();
    }

    public int indexOfList(ListField listField, String prefix, int start) {
        return content.indexOf(prefix, start);
    }
}

public int getCurrentPosition() {
    return currentPosition;
}

protected boolean navigationClick(int status, int time) {
    int index = getCurrentPosition();
    if (catsid[index] == 9) {
        if (Config_GlobalFunction.isConnected()) {
            webpage = new BrowserField();
            listener = new Custom_BrowserFieldListener();
            webpage.addListener(listener);

            MainScreen aboutus = new Menu_Aboutus();
            aboutus.add(webpage);
            Main.getUiApplication().pushScreen(aboutus);

            webpage.requestContent("http://www.orientaldaily.com.my/index.php?option=com_k2&view=item&id="
                    + newsid[index] + ":&Itemid=223");
        } else
            Config_GlobalFunction.Message(Config_GlobalFunction.nowifi, 1);
    } else
        Main.getUiApplication().pushScreen(
                new Main_NewsDetail(newsid[index]));
    return true;
}
}
于 2012-07-18T08:53:19.930 に答える
0

TableRowManager特定の値を持つレイアウトで、すべてのdrawRow設定値を1 つだけ持つのはどうですか?

于 2012-07-13T07:45:29.107 に答える
0

メモリ使用量を減らすためにできることはたくさんあります。1 つには、実際に必要な時間よりも長くオブジェクトをメモリに保持しないようにします。これが発生する 1 つの方法は、クラスにメンバー変数を保持する場合です。これは、実際にはメソッド内のローカル変数である可能性があります。メンバー変数を保持すると、オブジェクトが必要以上に長く存続し、それらが占有するメモリの解放を妨げる可能性があります。

Util_ImageLoader

たとえば、 ではUtil_ImageLoader、ほとんどすべての作業をコンストラクタで行います。しかし、その後、結果をBitmap静的メンバー変数 ( _bmap) の周り ( ) に保持し、メモリ内に保持します。を呼び出すことができるように、これを行うことを知っていますgetBitmap()。ただし、クラスを次のように変更できます。

public class Util_ImageLoader { 

   public static Bitmap loadImage(String url) {       
      HttpConnection connection = null; 
      InputStream inputStream = null; 
      EncodedImage bitmap; 
      byte[] dataArray = null; 

      try { 
         // can use this for BlackBerry 5.0+ :
         // connection = (HttpConnection) (new ConnectionFactory()).getConnection(url).getConnection();
         connection = (HttpConnection) Connector.open(url + Util_GetInternet.getConnParam(),  Connector.READ, 
               true); 
         int responseCode = connection.getResponseCode(); 
         if (responseCode == HttpConnection.HTTP_OK) { 
            inputStream = connection.openDataInputStream();
            dataArray = IOUtilities.streamToBytes(inputStream);            
         } 
      } catch (Exception ex) { 
      } 
      finally { 
         try { 
            inputStream.close(); 
            connection.close(); 
         } catch (Exception e) { 
         } 
      } 

      if (dataArray != null) {
         bitmap = EncodedImage.createEncodedImage(dataArray, 0, dataArray.length);        
         return bitmap.getBitmap(); 
      } else {
         return null;
      }
   } 
} 

Util_ImageLoaderクラスには実際には状態が関連付けられていないため、staticメソッドを 1 つだけ持つクラスにすることができます。静的メソッドを使用するために のインスタンスを作成する必要はありませんUtil_ImageLoader。これを行うだけです:

Bitmap img = Util_ImageLoader.loadImage("http://domain.com/path/image.png");

これにより、読み込まれた画像は、UI の処理が完了するとすぐに解放されます。既存のコードは、プログラムの存続期間中、そのイメージをメモリに保持します。

byte[]また、バッファを使用するカスタム コードを便利なIOUtilities.streamtoBytes()メソッドに置き換えました。組み込みライブラリに最適化の作業を任せてください。 ほとんどの場合、彼らはそれをかなりうまくやってくれます。

Util_ImageLoaderまた、クラスには何もしていない固定小数点スケーリング コードがいくつかありました。オリジナルと同じサイズの縮小画像を作成していました。だから、私はそのコードを削除しました。それはあなたのメモリ使用量を助けることができるだけです。画像操作にはコストがかかる場合があります。

最後に、このメソッドに必要な大きなオブジェクトを作成するに、Web サーバーのリターン コード ( HTTP_OK)を確認しました。ネットワーク リクエストが失敗した場合、理由もなくメモリを浪費したくはありません。

Custom_ListField

繰り返しになりますが、いくつかのオブジェクトを必要以上に長く保持している可能性があります。メンバー変数を見てみましょう。

private Bitmap bg = Bitmap.getBitmapResource("background.png"),          
    imagebitmap; 

アプリにのインスタンスがいくつあるかはわかりませんが、一定のアプリ リソース イメージCustom_ListFieldに割り当てるbg場合は、少なくともそれをstaticメンバー変数にして、 のインスタンスが 10 個ある場合はCustom_ListFieldbgメモリ内に 1 つの変数のみを保持します。

private static Bitmap bg = Bitmap.getBitmapResource("background.png"),          
    imagebitmap;

しかし、あなたの場合、そのメンバー変数を保持する必要はまったくないと思います。次のように、使用されている場所を簡単に置き換えることができます。

Background background = BackgroundFactory.createBitmapBackground(Bitmap.getBitmapResource("background.png")); 

次に、imagebitmapメンバーをローカル変数に置き換えることもできます。

 Bitmap imageBitmap = null;
 if (!imagepath[x].toString().equals("no picture")) {            
        imageBitmap = Util_ImageLoader.loadImage(imagepath[x]);            
        imageBitmap = loader.getbitmap();            
 } else {            
        imagepath[x] = "image_base.png";            
        imageBitmap = Bitmap.getBitmapResource(imagepath[x]);            
 }            
 image = new BitmapField(imageBitmap, Field.FIELD_HCENTER | Field.FIELD_VCENTER);        

imageBitmapメンバー変数ではなく、ローカル変数である必要があります。

通常、メモリ使用量をデバッグするには、プログラム全体を実行し、プロファイリングする必要があります。あなたのコードの一部だけでは、それを使用する他のすべてのコードを見ることができません。 各クラスの作成数は重要ですか? 大きい画像と小さい画像はどれ?これらはすべて、メモリ使用量を減らすために自問する必要がある質問です。

しかし、うまくいけば、上記の例で示した一般的なテクニックが、あなたが始めるのに役立つことを願っています.

于 2012-07-14T10:28:25.527 に答える