phonegap / cordova文案和阅读器无法正常工作

时间:2012-11-18 13:06:57

标签: android eclipse cordova

我正在使用cordova 2.2.0开发eclipse上的Android应用程序。它似乎获取Phonegap的文件API,但无法读取或写入文件。

我已经从xcode复制了脚本,我已经完成了iOS应用程序的运行。

这是我的脚本,用控制台输出跟踪:

window.onload = function (){
    console.log('1: onload');
    document.addEventListener("deviceready", getSettings, false);
}
function getSettings(){
    console.log('2: getSettings()');
    fileSys('settings.txt', 'getContent', null);
    //fileSys('settings.txt', 'replaceContent', 'new settings');
}
function fileSys(fileName, action, data){
    console.log('3: fileSys - '+fileName+' - '+action);
    var directory = (fileName == 'sidur') ? 'appin/sidur':'appin';
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
    function gotFS(fileSystem) {
    console.log('4: Got file system, get directory...');
    fileSystem.root.getDirectory(directory, {create: true}, gotDir, fail);
    }
    function gotDir(dirEntry) {
        console.log('5: Got directory. Get file...');
        dirEntry.getFile(fileName, {create: true, exclusive: false}, gotFileEntry, fail);
    }
    function gotFileEntry(fileEntry){
        console.log('6: got file. Perform action: '+action+'...');
        if(action == 'getContent') readAsText(fileEntry);
        if(action == 'replaceContent') fileEntry.createWriter(gotFileWriter, fail);
    }
    function gotFileWriter(writer){
        console.log('7: got file writer...');
        writer.write(data); //function variable of fileSys();
        writer.onwriteend = function(evt) {
        console.log('8: file written');
        };
    }
    function readAsText(file) {
        console.log('7: read as text...');
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onloadend = function(evt) {
            console.log('9: done reading file');
            init(evt.target.result);
        }
    }
    function fail(error){
        console.log('fail: '+error.code);

    }
}
function init(settings){
    console.log('Init. Settings: '+JSON.stringify(settings));
}

运行此脚本会提供以下控制台输出:

  • 1:onload
  • 2:getSettings()
  • 3:fileSys - settings.txt - getContent
  • 4:获得文件系统,获取目录......
  • 5:找到了目录。获取文件......
  • 6:得到了档案。执行操作:getContent ...
  • 7:读作文字......

它停止了。从不调用reader.onloadend,也没有指定错误。如果我再次运行,而是调用fileSys('settings.txt','replaceContent','new settings');并且取消对fileSys的另一个调用,控制台输出:

  • 1:onload
  • 2:getSettings()
  • 3:fileSys - settings.txt - replaceContent
  • 4:获得文件系统,获取目录......
  • 5:找到了目录。获取文件......
  • 6:得到了档案。执行操作:replaceContent ...
  • 7:有文件撰稿人......

我有:

  • 在res / config.xml和android manifest.xml
  • 中设置正确的权限/插件
  • 已验证Phonegap API已包含且正常工作(带通知)

我是应用程序开发和eclipse的新手,所以这很可能是我错过的一些基本的东西。任何建议和指示都是最受欢迎的。

2 个答案:

答案 0 :(得分:2)

好吧,我想出了这个。问题出在我的代码结构中。

这在ios上运行良好:

function readAsText(file) {
    var reader = new FileReader();
    reader.readAsText(file);
    reader.onloadend = function(evt) {
        console.log('9: done reading file');
        init(evt.target.result);
    };
}

但不知何故,Android的phonegap要求你在阅读器的readAsText方法之上为阅读器的onloadend方法声明变量。像这样:

function readAsText(file) {
    var reader = new FileReader();
    reader.onloadend = function(evt) {
        console.log('9: done reading file');
        init(evt.target.result);
    };
    reader.readAsText(file);
}

回想起来,这对我来说非常有意义。 iOS允许反过来似乎很奇怪。

答案 1 :(得分:1)

实际上,它不是你的陈述的顺序,因为Android和iOS都会以相同的顺序解释它们。不同的是readAsText完成的速度,因为它的工作在另一个线程中异步发生。这是iOS上发生的事情的一个例子:

reader.readAsText - this starts the read process in another thread
reader.onloadend = function... - you set up your handler
-- on separate thread, readAsText finally completes and sees your handler and calls it

这就是Android上发生的事情:

reader.readAsText - this starts the read process in another thread
-- on separate thread, readAsText completed quickly but your handler has not been set yet so it does not get called
reader.onloadend = function... - you set up your handler too late, the read already completed in its own thread

在异步调用中,您无法保证其他任务何时完成。它与Android和iOS之间没有区别,它只是多线程操作的本质。有各种方法来处理异步调用(正确地排序和嵌套回调,使用jquery延迟,某种类型的信号量机制,以及更多,我确定)。最重要的是,永远不要依赖或假设任务将在一定时间内完成。对时间的依赖会让你大吃一惊,而且非常难以调试。