0

如何异步显示从列表字段上的 url 获取的图像?运行代码时出现异常。这是我的代码。我收到未捕获的 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. 相反,您应该在屏幕中有一个单独的工作线程来下载图像。您可以使用消费者-生产者模式:用户在向下滚动时生成图像下载请求(生产者),工作线程(消费者)将它们排入队列以进行处理。您可以使用由 Vector 定制的 LIFO 结构,并且wait在没有请求的情况下使用它。
  • 您应该提供一个默认图像,以便在尚未下载真实图像时显示。
  • 我几乎可以肯定您当前的代码对于hst哈希表来说不是线程安全的。您应该确保您的使用者是线程安全的。网上有很多关于如何做到这一点的例子。
  • 当然,当用户更改屏幕时,工作线程应该终止。在您当前的代码中,即使用户已切换到另一个屏幕,线程仍将保持活动状态并尝试更新哈希表。

作为一种优化,如果您提前知道您的应用程序通常有多少线程(不计算图像),并且您知道不会超过最大线程限制,那么您可以拥有一个线程池,比如说, 5 个线程来下载图像,而不是单个工作线程。当所有 5 个线程都忙时,您将开始对请求进行排队。您还可以添加每个请求的最大时间机制,以防止线程忙于下载失败,因此不是在 2 分钟超时,而是在 30 秒超时并发出第二个请求。

于 2012-05-07T10:59:56.267 回答
0

什么是 HttpUtils.getBitmap()?如果它是为 Java-SE 编写的 Java 代码,那么它在 BlackBerry 上将无法正常工作,因为 BlackBerry 设备仅支持 Java-ME,其功能远低于现代 Java-SE 运行时。

至于异步加载,您需要在获取完成后将事件传回 UI。如果您一次获取多张照片,您还需要为该事件添加某种批处理,因为为每张照片发送一个事件可能会超出 UI 应用程序上的事件队列。

于 2012-05-06T15:57:09.490 回答