LWUIT: загрузка изображений в фоновом потоке - PullRequest
2 голосов
/ 08 декабря 2011

У меня есть список, содержащий около 20 URL-адресов изображений и некоторые другие вещи.

Я хочу отобразить другие элементы (описание) и разрешить пользователю взаимодействовать с приложением, пока я загружаю 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 ]

2 голосов
/ 08 декабря 2011

ПОДХОД I: LWUIT 1.5 имеет мощную библиотеку LWUIT4IO для решения вашей проблемы.

Отрывок из Ссылка на блог Шая

Особенностью LWUIT4IO , на которую я не обратил достаточного внимания, является карта кеша, фактически эффективная хеш-таблица, в которой хранятся данные используя слабые / мягкие ссылки (в зависимости от платформы) и отступает в хранилище, когда недостаточно памяти. Это отличный способ кэшировать данные, не выходя за борт. Одна из классных вещей об этом тот факт, что мы используем его незаметно для нашей абстракции хранилища (что скрывает RMS или эквивалентные службы), обеспечивая более быстрый доступ к Среднеквадратичное хранилище, которое часто работает медленно на устройствах.

Другая полезная ссылка здесь

Идея состоит в том, чтобы делегировать функциональные возможности сетевого ввода-вывода в одноэлементный режим, чтобы избежать любых взаимоблокировок пользовательского интерфейса, например той, с которой вы столкнулись.

Очень хорошая демонстрация видео здесь от vprise, объясняет, как привязать функциональность GUI к вашим сетевым компонентам. В этом видео около 7:00 минут он объясняет использование класса ImageDownloadService, который привязывает компонент к его URL-адресу миниатюр, который будет беспрепятственно извлекаться из сети и заполнять изображение.

ПОДХОД II: Сложно создать собственную логику

  1. Создать синглтон, который будет взаимодействовать с сетью для извлечения данные
  2. Использование очереди для обработки сервисов последовательной загрузки изображений
  3. Создайте новый поток для этого синглтона и дождитесь очереди.
  4. С каждым сервисом загрузки изображений связывайте слушателя с вызовом компонента, чтобы было проще обновить нужный компонент.
1 голос
/ 08 декабря 2011

Согласно спецификации lwuit, callSerially () выполняется в потоке диспетчеризации событий, что означает, что он будет блокировать другие события, пока не завершится. Вам нужно переместить свой код, чтобы загрузить изображение за пределы этого метода и оставить только вызовы setText и setIcon в callSerially ().

...