Индикатор выполнения Blackberry во время загрузки - PullRequest
1 голос
/ 14 июля 2011

Я работаю над приложением для blackberry, которое будет загружать файл.Я хотел бы показать индикатор выполнения во время этой загрузки.Я перепробовал каждую комбинацию GaugeField и ProgressIndicatorView, которую могу придумать, но ничего не получаю.Моя загрузка продолжается, но индикатор прогресса никогда не обновляется на экране.Фактически, до того, как я начал пробовать индикатор выполнения, я пытался просто использовать TextField и обновить его с текущим процентом завершения загрузки, и мне тоже не повезло.

Это внутри моего экрана:

    view = new ProgressIndicatorView(0);
    model = new ProgressIndicatorModel(0, 100, 0);
    controller = new ProgressIndicatorController();   


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

    view.setLabel("Percent completion");
    view.createProgressBar(Field.FIELD_HCENTER);       

    add(view);

    UiApplication.getUiApplication().invokeLater(new Runnable()
    {
        public void run()
        {
            downloadVideo();
            initializeMedia();                

            // If initialization was successful...
            if(_videoField != null)
            {                    
                createUI();                   

                updateVideoSize();   

                try {
                    _player.start();

                } catch (MediaException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    ScreenSaverActivity.errorDialog("MEDIA EXCEPTION: "+e.toString());
                }
            }
            else
            {
                _statusField.setText("Error: Could not load media");
            }
        }
    });                      

Метод downloadVideo ():

private void downloadVideo(){

    DownloadThread _dlThread = new DownloadThread();

    _dlThread.start();

}

Класс DownloadThread:

class DownloadThread extends Thread {
    public void run(){

        try {
            HttpConnection httpConn;
            httpConn = (HttpConnection)Connector.open("http://url/to/myMovie.mp4");
            InputStream is = httpConn.openInputStream();

            String fName = "file:///store/BlackBerry/videos/myMovie.mp4";


            FileConnection fconn = (FileConnection) Connector.open(fName, Connector.READ_WRITE);
            if (!fconn.exists())
                fconn.create();

            OutputStream os = fconn.openOutputStream();
            long lengthOfFile = httpConn.getLength();
            int total = 0;
            int count;
            byte data[] = new byte[1024];
            while ((count = is.read(data)) != -1) {
                //I have tried this line outside of synchronized too, with no luck
                synchronized(Application.getEventLock()) {
                    EmbeddedMediaScreen.this.model.setValue((int)(total*100/lengthOfFile));
                }

                total += count;
              //write this chunk
                os.write(data, 0, count);
            }
            os.flush();
            os.close();
        } catch (IOException e) {
            ScreenSaverActivity.errorDialog(e.toString());
            e.printStackTrace();
        }
    }
}

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

PS Обычно Android - это мой дом, а не ежевика, извините, если я упустил из виду то, что должно быть очевидным = /

1 Ответ

2 голосов
/ 14 июля 2011

Я вижу несколько вопросов.Похоже, что код после 'downloadVideo ()' предполагает, что загрузка происходила синхронно.Поскольку вы хотите, чтобы загрузка происходила в фоновом режиме, вам нужно настроить отдельный метод для обработки завершения загрузки.Прямо сейчас ваш код воспроизведения видео выполняется сразу после запуска потока загрузки.

Кроме того, вы получаете блокировку событий пользовательского интерфейса каждые 1k загрузки.Поскольку это видео, я предполагаю загрузку в несколько мегабайт, то есть вы приобретаете и выпускаете эту блокировку тысячи раз.Это не имеет особого смысла, отчасти потому, что счетчик загрузок имеет только 100 различных значений, поэтому вы в основном обновляете его с тем же значением.Самым простым решением является отслеживание последнего значения, отправленного модели.если оно не изменилось, не получайте и не обновляйте значение.

В общем, я не люблю напрямую получать блокировку пользовательского интерфейса, поскольку управление очередями отсутствует.Поэтому я использую invokeLater для всего кода, который требуется для обновления пользовательского интерфейса.Это имеет приятное свойство, что код invokeLater происходит последовательно.Вы можете переполнить очередь, как сделал бы этот код, если бы вы непосредственно изменили его на invokeLater.Чтобы избежать этой проблемы, вам нужно настроить другую переменную, чтобы отслеживать, есть ли у вас в очереди обновление индикатора прогресса.Если это так, не стоит больше работать в очереди.

...