2011-07-14 3 views
1

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

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

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(); 
     } 
    } 
} 

В то время как мое приложение делает загрузку устройство перестает отвечать на запросы , поэтому я предполагаю, что моя проблема заключается в том, что загрузка загружается на главном (UI) threa d по какой-то причине и что это имеет какое-то отношение к тому, почему я не могу заставить экран обновляться с прогрессом. Любая помощь будет принята с благодарностью.

P.S. Android, как правило, мой дом, а не ежевика, извините, если я упустил что-то, что должно быть очевидно =/

ответ

2

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

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

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

+0

Вы заставили меня идти в правильном направлении. Он работает сейчас. Будет опубликовать код, который работал для меня немного. Благодаря тонну! – FoamyGuy

Смежные вопросы