【问题标题】:Blackberry progress bar during download下载过程中的黑莓进度条
【发布时间】:2011-07-14 14:40:10
【问题描述】:

我正在开发一个用于下载文件的黑莓应用程序。我想在下载过程中显示一个进度条。我已经尝试了我能想出的 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();

}

下载线程类:

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)线程上发生,这与我为什么不能t 获取屏幕以更新进度。任何帮助将不胜感激。

附: Android 通常是我的家,而不是黑莓,如果我忽略了一些应该很明显的东西,请见谅 =/

【问题讨论】:

    标签: blackberry download progress-bar


    【解决方案1】:

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

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

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

    【讨论】:

    • 你让我朝着正确的方向前进。它现在正在工作。稍后将发布对我有用的代码。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    相关资源
    最近更新 更多