LWUIT:在后台线程中加载图像

时间:2011-12-07 20:37:06

标签: java multithreading lwuit

我有一个包含大约20个图片网址和其他一些内容的列表。

我想显示其他内容(说明),并允许用户在加载20张图片时与应用互动。

我注意到的是,无论我尝试什么,我都无法与图像交互,直到图像完成加载,即使我正在另一个线程中加载。

这是我现在使用的解决方案。

private Container createServerItems() throws Exception {
    Container list = new Container(new BoxLayout(BoxLayout.Y_AXIS));

    final int size = mediaList.size();

    final Button buttons[] = new Button[size];

    System.out.println("In here: " + size);
    for (int i = 0; i < size; i++) {
        Container mainContainer = new Container(new BorderLayout());
        Media m = new Media();
        m.fromJSONString(mediaList.elementAt(i).toString());

        buttons[i] = new Button("please wait");

        final int whichButton = i;
        Display.getInstance().callSerially(new Runnable() {

            public void run() {
                try {
                    System.out.println(MStrings.replaceAll(m.getImgURL(), "\"", ""));
                    final StreamConnection streamConnection = (StreamConnection) Connector.open(MStrings.replaceAll(m.getImgURL(), "\"", ""));                        
                    Image image = Image.createImage(streamConnection.openInputStream());
                    streamConnection.close();

                    buttons[whichButton].setText("");
                    buttons[whichButton].setIcon(image.scaled(32, 32));

                } catch (Exception e) {
                }
            }
        });
        TextArea t = new TextArea(m.getDesc());
        t.setEditable(false);
        t.setFocusable(false);
        t.setGrowByContent(true);

        mainContainer.addComponent(BorderLayout.WEST, buttons[i]);
        mainContainer.addComponent(BorderLayout.CENTER, t);

        list.addComponent(mainContainer);
    }
    return list;
}

2 个答案:

答案 0 :(得分:2)

APPROACH I: LWUIT 1.5 有一个功能强大的 LWUIT4IO 库来解决您的问题。

Shai's Blog link

的摘录
  

我没有给予足够关注的 LWUIT4IO 中的一项功能是   缓存映射,它实际上是一个存储其数据的精简哈希表   使用弱/软引用(取决于平台)并退回   没有足够的内存可用于存储。这是一个很好的方式   缓存数据而不会过度。关于它的一个很酷的事情是   事实上,我们无缝地使用它来进行存储抽象(其中   隐藏RMS或等效服务)实际上提供了更快的访问权限   RMS存储在设备上通常很慢。

另一个有用的链接是here

我们的想法是将网络IO功能委派给单例,以避免任何UI死锁,例如您所面临的死锁。

vprise的一个非常好的视频演示here,解释了如何将GUI功能绑定到netbeans。在大约7点钟的视频中,它解释了使用ImageDownloadService类将组件绑定到其缩略图网址,该网址将从网络无缝获取并填充图像。

APPROACH II:创建自定义逻辑的难度

  1. 创建一个与网络接口的单例以获取 数据
  2. 使用队列处理顺序图像下载服务
  3. 为此单例创建一个新线程并等待队列。
  4. 每个图像下载服务都会通过调用绑定一个侦听器 组件,以便更新正确的组件。

答案 1 :(得分:1)

根据lwuit规范,callSerially()在Event Dispatch Thread上执行,这意味着它将阻止其他事件,直到它完成。您需要移动代码以在该方法之外加载图像,并且只在callSerially()中保留setText和setIcon调用。