Индикатор активности и темы ежевики - PullRequest
0 голосов
/ 29 июня 2011

Я работаю над проектом, где я загружаю из файла из Интернета, он невелик, всего несколько КБ.

Мой макет представляет собой список с меткой под ним. Когда пользователь обновляется (проверяет, доступен ли новый файл), я хочу заменить метку индикатором активности.

Я загружаю файл в отдельном потоке, чтобы не блокировать основной поток. Но у меня проблемы с индикатором активности. Я использую UiApplication.getUiApplication().invokeLater(//CODE);, чтобы удалить метку из менеджера и добавить индикатор активности, а также запустить его. Это правильно? Я делаю это в потоке загрузки файлов, и правильно ли, что вам нужно вызывать код GUI из основного потока?

затем у меня есть блок кода (все это внутри метода run потока загрузки файлов), который загружает отчет, затем у меня есть новый метод invokeLater, который удаляет индикатор активности и снова добавляет метку.

Однако это не работает должным образом, поскольку последний код invokeLater запускается перед первым. Я проверил с диалогами. Как я мог решить это?

Я хочу, чтобы он запускал код в том порядке, в котором я его кодировал, и ни один код не запускался до того, как другие закроются. Как я мог это сделать?

(и да, я знаю, что это грязно!)

private class UpdateReportThread extends Thread {
        public void run() {
            super.run();

            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    view = new ActivityIndicatorView(Field.FIELD_HCENTER);
                    model = new ActivityIndicatorModel();
                    controller = new ActivityIndicatorController();

                    view.setController(controller);
                    view.setModel(model);
                    controller.setModel(model);
                    controller.setView(view);
                    model.setController(controller);    

                    Bitmap bitmap = Bitmap.getBitmapResource("spinner.jpg");
                    view.createActivityImageField(bitmap, 5, Field.FIELD_HCENTER);

                    dialogManager = new VerticalFieldManager(Manager.FIELD_HCENTER | Manager.FIELD_VCENTER | Manager.USE_ALL_HEIGHT);
                    dialogManager.add(new LabelField("Please wait...", Field.FIELD_HCENTER));
                    dialogManager.add(view);

                    add(dialogManager);     
                    view.getModel().resume();

                    delete(lblIssueWeek);
                    delete(lblIssueYear);
                }
            });


            //File downloading code
                    //File downloading code
                    //File downloading code    

            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    view.getModel().cancel();
                    delete(dialogManager);

                    lblIssueWeek = new LabelField("", LabelField.FIELD_HCENTER);
                    lblIssueYear = new LabelField("", LabelField.FIELD_HCENTER);
                    add(lblIssueWeek);
                    add(lblIssueYear);
                    updateCurrentIssue();
                }
            });
        }
    }

Ответы [ 2 ]

2 голосов
/ 29 июня 2011

Если вы видите, что invokeLater runnables запускаются в неправильном порядке, то, похоже, у вас есть три варианта:

  1. Продолжайте использовать invokeLater и сохраняйте некоторые логические поля (или некоторые эквивалентные), которые сообщают вам, завершена ли загрузка, и показывает ли индикатор активности. В вашем первом invokeLater индикатор будет отображаться только в том случае, если загрузка еще не завершена; а во второй invokeLater вы удалили бы индикатор, только если он был показан.
  2. Используйте invokeAndWait вместо invokeLater. invokeAndWait вызовет runnable как можно скорее и остановит выполнение в текущем потоке, пока не будет вызван runnable. Это уменьшит степень распараллеливания, но изменение полей в любом случае является быстрой операцией, поэтому в этом случае это не должно иметь большого значения
  3. Вместо использования invokeAndWait с Runnable, используйте блок synchronized(Application.getEventLock()) вокруг кода, который добавляет и удаляет поля. Вы можете манипулировать пользовательским интерфейсом даже вне потока пользовательского интерфейса, если вы синхронизированы с блокировкой событий приложения. В этой статье еще немного говорится о блокировках событий.

Я бы порекомендовал третий вариант, так как он самый надежный. Однако вы должны знать, что существуют определенные операции, такие как появление модального диалогового окна, которое может только быть выполненным из потока пользовательского интерфейса (удержание блокировки события недостаточно). В этих случаях вам нужно будет выбрать один из двух других вариантов. Однако из того, как вы описали то, что вы пытаетесь сделать, удержание блокировки события должно быть достаточно в этой ситуации.

0 голосов
/ 29 июня 2011

Найти эту тему

Blackberry - Экран загрузки / ожидания с анимацией

Это хороший пример, показывающий индикатор ожидания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...