0

URLから取得した画像をリストフィールドに非同期で表示するには? コードを実行すると例外が発生します。これが私のコードです。Uncaught NoClassFoundError が発生しています

private Bitmap getBitmap(final String strEventCode)
{
    if(hst.containsKey(strEventCode))
        return (Bitmap) hst.get(strEventCode);
    else
    {           
        Thread t = new Thread(new Runnable() 
        {
            public void run() 
            {                       
                Bitmap bmp = HttpUtils.getBitmap(strHalfUrl+strEventCode+".jpg");
                hst.put(strEventCode, bmp);
            }
        });
        t.start();
    }
    return null; 
}

ListFieldCallBack を使用して次のコードを使用して画像を描画します。

class ListCallBack implements ListFieldCallback
{       
   public  void drawListRow(final ListField list, final net.rim.device.api.ui.Graphics g, final int index, final int y, final int w)
   {                  
       Event objEvent = (Event) eventData.elementAt(index);
       if(list.getSelectedIndex() == index)
       {              
           g.setColor(Color.LIGHTGRAY);
           g.fillRect(0, y, getWidth(), getHeight());            
       }
       Bitmap bmp = getBitmap(objEvent.getStrName());
       if(bmp==null)
           g.drawBitmap(0, y+5, loadingImage.getWidth(),loadingImage.getHeight(),loadingImage, 0, 0);
       else
           g.drawBitmap(0, y+5, bmp.getWidth(),bmp.getHeight(),bmp, 0, 0);

       g.setColor(Color.BLACK);
       int yPos = y + list.getRowHeight() - 1;
       g.drawLine(0, yPos, w, yPos);

       //final Bitmap b=(Bitmap)myImages.elementAt(index);
       //g.drawBitmap(0, y+5, b.getWidth(),b.getHeight(),b, 0, 0);         
   } 
   public Object get(ListField list, int index)
   { 
       return eventData.elementAt(index); 
   } 
   public int getPreferredWidth(ListField list)
   {
       return Display.getWidth();
   }
   public int indexOfList(ListField listField, String prefix, int start) 
   {
      return eventData.indexOf(prefix,start);
   }
}
4

2 に答える 2

1

私はいくつかのことを変更します:

  • BB では、生成できるスレッドの最大数があり、それは <20 だと思います。画像ごとにスレッドを生成しているため、遅かれ早かれTooManyThreadsException. 代わりに、画像をダウンロードする単一のワーカー スレッドを画面に配置する必要があります。コンシューマー プロデューサー パターンを使用できます。ユーザーが下にスクロールすると、画像のダウンロード リクエスト (プロデューサー) が生成され、ワー​​カー スレッド (コンシューマー) がそれらを処理するためにキューに入れます。ベクターからカスタム作成された LIFO 構造体を使用でき、waitリクエストがない間はその上で使用できます。
  • 実際の画像がまだダウンロードされていない間に表示するデフォルトの画像を提供する必要があります。
  • hstハッシュテーブルに関して、現在のコードがスレッドセーフではないことはほぼ確実です。コンシューマーがスレッドセーフであることを確認する必要があります。これを行う方法については、ネットにたくさんの例があります。
  • もちろん、ユーザーが画面を変更すると、ワーカー スレッドは終了する必要があります。現在のコードでは、ユーザーが別の画面に移動した場合でも、スレッドは存続し、ハッシュテーブルを更新しようとします。

最適化として、アプリが通常 (画像をカウントせずに) いくつのスレッドを持っているかを事前に知っていて、最大スレッド数の制限を超えないことがわかっている場合は、次のようなスレッド プールを持つことができます。単一のワーカー スレッドではなく、5 つのスレッドでイメージをダウンロードします。5 つのスレッドすべてがビジー状態になったら、リクエストのエンキューを開始します。また、要求メカニズムごとに最大時間を追加して、ダウンロードの失敗でスレッドがビジー状態になるのを防ぐこともできます。そのため、2 分でタイムアウトするのではなく、30 秒でタイムアウトして、2 番目の要求を行います。

于 2012-05-07T10:59:56.267 に答える
0

HttpUtils.getBitmap() とは何ですか? Java-SE 用に記述された Java コードの場合、BlackBerry ではうまく機能しません。BlackBerry デバイスは、最新の Java-SE ランタイムよりも大幅に機能が少ない Java-ME しかサポートしていないためです。

非同期読み込みに関しては、フェッチが完了したらイベントを UI に戻す必要があります。一度に多くの写真を取得する場合は、そのイベントに何らかのバッチ処理を追加することもできます。これは、写真ごとにイベントを送信すると、UI アプリのイベント キューがオーバーランする可能性があるためです。

于 2012-05-06T15:57:09.490 に答える