我正在使用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));
}
运行此脚本会提供以下控制台输出:
它停止了。从不调用reader.onloadend,也没有指定错误。如果我再次运行,而是调用fileSys('settings.txt','replaceContent','new settings');并且取消对fileSys的另一个调用,控制台输出:
我有:
我是应用程序开发和eclipse的新手,所以这很可能是我错过的一些基本的东西。任何建议和指示都是最受欢迎的。
答案 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延迟,某种类型的信号量机制,以及更多,我确定)。最重要的是,永远不要依赖或假设任务将在一定时间内完成。对时间的依赖会让你大吃一惊,而且非常难以调试。