0

我有一个 phonegap 应用程序(Android)。我使用插件Downloader来下载 xml 文件。当我下载文件时,我的应用程序会“暂停”,直到下载完成。我不能点击任何东西,我的装载机不工作等等。

它曾经可以正常工作,但我不得不将我的应用程序从 cordova 1.8.0 升级到新版本(2.7.0)。

我还更改了插件本身以与新的cordova一起使用。

我不知道这是什么原因造成的。有任何想法吗?。

-------编辑:添加代码------

这是我的下载器插件类

public class Downloader extends CordovaPlugin {

public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {


    if (!action.equals("downloadFile")){
        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.INVALID_ACTION));
        return true;
    }
    try {

        String fileUrl = args.getString(0);
        JSONObject params = args.getJSONObject(1);

        String fileName = params.has("fileName") ? 
                params.getString("fileName"):
                fileUrl.substring(fileUrl.lastIndexOf("/")+1);

        String dirName = params.has("dirName") ?
                params.getString("dirName"):
                    Environment.getExternalStorageDirectory().toString();

        Boolean overwrite = params.has("overwrite") ? params.getBoolean("overwrite") : false;

        callbackContext.sendPluginResult(this.downloadUrl(fileUrl, dirName, fileName, overwrite, callbackContext));
        return true;

    } catch (JSONException e) {

        e.printStackTrace();
        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage()));
        return false;

    } catch (InterruptedException e) {
        e.printStackTrace();
        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, e.getMessage()));
        return false;
    }

}
private PluginResult downloadUrl(String fileUrl, String dirName, String fileName, Boolean overwrite, CallbackContext callbackContext) throws InterruptedException, JSONException {


    try {

        Log.d("PhoneGapLog", "Downloading "+fileUrl + " into " + dirName + "/" + fileName);

        File dir = new File(dirName);
        if (!dir.exists()) {
            Log.d("PhoneGapLog", "directory " + dirName + " created");
            dir.mkdirs();
        }

        File file = new File(dirName, fileName);

        if (!overwrite && file.exists()) {
            Log.d("DownloaderPlugin", "File already exist");

            JSONObject obj = new JSONObject();
            obj.put("status", 1);
            obj.put("total", 0);
            obj.put("file", fileName);
            obj.put("dir", dirName);
            obj.put("progress", 100);

            return new PluginResult(PluginResult.Status.OK, obj);
        }

        URL url = new URL(fileUrl);
        HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
        ucon.setRequestMethod("GET");
        ucon.connect();

        Log.d("PhoneGapLog", "Download start");

        InputStream is = ucon.getInputStream();
        byte[] buffer = new byte[1024];
        int readed = 0, 
            progress = 0,
           // totalReaded = 0,
            fileSize = ucon.getContentLength();

        FileOutputStream fos = new FileOutputStream(file);

        while ((readed = is.read(buffer)) > 0) {

            fos.write(buffer, 0, readed);
            //totalReaded += readed;

            //int newProgress = (int) (totalReaded*100/fileSize);               
            //if (newProgress != progress)
            // progress = informProgress(fileSize, newProgress, dirName, fileName, callbackId);

        }

        fos.close();

        Log.d("PhoneGapLog", "Download finished");

        JSONObject obj = new JSONObject();
        obj.put("status", 1);
        obj.put("total", fileSize);
        obj.put("file", fileName);
        obj.put("dir", dirName);
        obj.put("progress", progress);

        return new PluginResult(PluginResult.Status.OK, obj);


    }
    catch (FileNotFoundException e) {
        Log.d("PhoneGapLog", "File Not Found: " + e);
        return new PluginResult(PluginResult.Status.ERROR, 404);
    }
    catch (IOException e) {
        Log.d("PhoneGapLog", "Error: " + e);
        return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
    }
}

}

这是我的下载器插件 javascript

function Downloader() {}

Downloader.prototype.downloadFile = function(fileUrl, params, win, fail) {
//Make params hash optional.
if (!fail) win = params;
return cordova.exec(win, fail, "Downloader", "downloadFile", [fileUrl, params]);
};

 if(!window.plugins) {
    window.plugins = {};
 }
 if (!window.plugins.downloader) {
   window.plugins.downloader = new Downloader();
 }

当我调用它时

$.mobile.showPageLoadingMsg();
window.plugins.downloader.downloadFile("URL",
                        {overwrite: true,
                        dirName: dir, fileName: "File.xml"}, 
                      function() {
                            alert("finished");      
                    }, function(error) {
                        alert("fail");
                );

由于 showPageLoadingMsg 而出现的加载程序将冻结直到下载完成或仅在下载完成后显示

4

1 回答 1

1

PhoneGap 插件方法在整个应用程序的 UI 线程上调用,你不应该在 UI 线程中执行长时间的活动,否则它会被阻塞,没有 UI 更新,甚至整个应用程序变得不负责任。请阅读文档 - 您应该在单独的线程中执行长任务,将 UI 线程释放到 PhoneGap。它分两步制作 - 你开始一个新线程并返回

PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
r.setKeepCallback(true);
callContext.sendPluginResult(r);

带有一个标志,它将是一个异步插件调用。当线程完成时,您完成调用

callContext.success(json);

编辑:

我错了 Cordova 插件方法是在 UI 线程上调用的,它们是在 WebCore 线程上调用的,这与 UI 线程不同(重要的是要记住是否需要在插件中显示一些 UI)。无论如何,您也不应该阻止 WebCore 线程,请参阅文档:

穿线

WebView 中的 JavaScript不在UI 线程上运行。它在 WebCore 线程上运行。execute 方法也在 WebCore 线程上运行。

http://docs.phonegap.com/en/2.2.0/guide_plugin-development_android_index.md.html

于 2013-09-11T19:50:52.757 回答