Output delayed from Cordova Plugin
Asked Answered
M

1

7

I've written a Cordova plugin to download a file and save it in the data folder. Everything is working fine except for the return value. I would like to display a progress bar and need to get the current progress. Here's the relevant part from my code:

 while ((readed = is.read(buffer)) > 0) {
     fos.write(buffer, 0, readed);
     totalReaded += readed;

     int newProgress = (int) (totalReaded*100/fileSize);
     if (newProgress != progress) {
         progress = newProgress;
         PluginResult res = new PluginResult(PluginResult.Status.OK, progress);
         res.setKeepCallback(true);
         callbackContext.sendPluginResult(res);
     }
  }

My JavaScript:

downloader.prototype.writeFile = function (downloaderSuccess, downloaderFailure, options) {
    cordova.exec(downloaderSuccess, downloaderFailure, "downloader", "writeFile", options);
};

function downloaderSuccess(progress) {
    WL.Logger.debug("Result: "+progress)
}

function downloaderFailure(error) {
    WL.Logger.error("Error: "+error);
}

What happens is that the progress will only be output after the file has been downloaded. If I set the PluginResult.Status to NO_RESULT, it won't output anything at all.

Manvel answered 19/3, 2013 at 17:4 Comment(0)
T
6

are you using

   cordova.getThreadPool().execute(new Runnable() {
            public void run() {
                // while loop goes here
            }
        });

in the start of your download code?

Have a look at src/org/apache/cordova/FileTransfer.java. This files does pretty much what you are doing and you can see how they are able to send live progress updates because they are in a separate thread.

I think the problem is that both the JavaScript and the Java code run in the same WebCore thread so what is happening is that the download is blocking the communication between Java and the UI (eg, sending the result) until the download is done.

If you follow the advice in that guide about not blocking the WebCore thread (so, use: cordova.getThreadPool().execute()), you'll be able to get progress updates.

To test this, I took this plugin: https://github.com/phonegap/phonegap-plugins/blob/master/Android/Downloader/Downloader.java that does File downloading. As it stands, this code behaves the same as yours does - the progress update is sent only after the file is downloaded. However, once I wrapped the downloadUrl() method in the runnable, it worked fine, sending progress updates as they happened instead of waiting until the end.

Please let me know if this helps or if you'd like me to come up with a better explanation.

Telugu answered 10/4, 2013 at 14:21 Comment(2)
Thanks for your answer. I ended up using the Phonegap download functions instead, but pointing me to the cordova.getThreadPool was useful for other parts of the app :)Chewy
You're welcome, glad that you were able to figure something out!Telugu

© 2022 - 2024 — McMap. All rights reserved.