Android phonegap/cordova文件写入程序和读取器不工作
我正在用cordova 2.2.0在eclipse上开发一个Android应用程序。它似乎获取了Phonegap的文件API,但无法读取或写入文件 我已经从xcode复制了这个脚本,在那里我已经完成了iOS应用程序,它可以正常工作 以下是我的脚本,通过控制台输出进行跟踪:Android phonegap/cordova文件写入程序和读取器不工作,android,eclipse,cordova,Android,Eclipse,Cordova,我正在用cordova 2.2.0在eclipse上开发一个Android应用程序。它似乎获取了Phonegap的文件API,但无法读取或写入文件 我已经从xcode复制了这个脚本,在那里我已经完成了iOS应用程序,它可以正常工作 以下是我的脚本,通过控制台输出进行跟踪: window.onload = function (){ console.log('1: onload'); document.addEventListener("deviceready", getSettin
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:空载
- 2:getSettings()
- 3:fileSys-settings.txt-getContent
- 4:获取文件系统,获取目录
- 5:找到了目录。获取文件
- 6:我拿到文件了。执行操作:getContent
- 7:以文本形式阅读
- 1:空载
- 2:getSettings()
- 3:fileSys-settings.txt-replaceContent
- 4:获取文件系统,获取目录
- 5:找到了目录。获取文件
- 6:我拿到文件了。执行操作:替换内容
- 7:有文件写入器
- 在res/config.xml和android manifest.xml中设置正确的权限/插件
- 已验证Phonegap API是否包含并正在使用(带有通知)
我对应用程序开发和eclipse都是新手,所以这很可能是我错过的一些基本东西。欢迎提出任何建议和建议。好吧,我想出来了。问题在于我的代码结构 这在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允许了另一种方式。事实上,这不是你陈述的顺序,因为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之间没有区别,这只是多线程操作的本质。有各种各样的方法来处理异步调用(正确地排序和嵌套回调,使用jquerydeferred,某种类型的信号量机制,等等,我确信)。最重要的是,永远不要依赖或假设任务会在一定时间内完成。依赖计时会让你很难调试。需要以这种方式定义它的原因是,在设置onloadend侦听器之前,你的读取已经成功。是的,这非常有意义。但奇怪的是,它在iOS中的工作方式正好相反。所以我猜这都是关于每个浏览器解释代码和定义变量的顺序。