下载期间黑莓进度栏

时间:2011-07-14 14:40:10

标签: blackberry download progress-bar

我正在处理将要下载文件的黑莓应用程序。我想在此下载过程中显示进度条。我已经尝试过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:

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)线程上ha并且这与我为什么能够做到这一点' t让屏幕随着进度更新。任何帮助将不胜感激。

P.S。 Android通常是我的家,而不是黑莓,对不起,如果我忽略了一些显而易见的事情= /

1 个答案:

答案 0 :(得分:2)

我看到一些问题。它看起来像'downloadVideo()'之后的代码假定下载同步发生。由于您希望下载在后台进行,因此您需要设置一个单独的方法来处理下载的完成。现在,您的视频播放代码在下载线程启动后立即执行。

此外,您每下载1k即获取UI事件锁定。由于这是一个视频,我假设你下载了数兆字节,这意味着你正在获取并释放数千次锁定。这没有多大意义,部分原因是因为下载仪表只有100个不同的值,因此您主要使用相同的值更新它。最简单的解决方法是跟踪发送给模型的最后一个值。如果没有变化,则不要获取或更新该值。

一般来说,我不喜欢直接获取UI锁,因为没有队列管理。所以我将invokeLater用于需要更新UI的所有代码。这有一个很好的属性,invokeLater代码顺序发生。您可以超出队列,因为如果直接将其更改为invokeLater,此代码将执行此操作。要避免该问题,您必须设置另一个变量来跟踪是否有排队的进度表更新。如果是这样,请不要再排队。