2012-11-18 44 views
1

我正在用cordova 2.2.0在eclipse上開發一個Android應用程序。它似乎獲取Phonegap的文件API,但無法讀取或寫入文件。phonegap/cordova filewriter和閱讀器不能正常工作

我已經從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');和outcomment其他呼叫的filesys,控制檯輸出:

  • 1:的onload
  • 2:的getSettings()
  • 3:的filesys - SETTINGS.TXT - replaceContent
  • 4:得到的文件系統,得到目錄...
  • 5:有目錄。獲取文件...
  • 6:有文件。執行操作:replaceContent ...
  • 7:拿到文件寫入...

我:

  • 設置在res/config.xml並在Android清單正確的權限/插件.XML
  • 驗證了PhoneGap的API包括與工作(與通知)

我新的應用程序開發,以及日食,所以這很可能是我錯過的一些基本的東西。任何建議和指針是最受歡迎的。

回答

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延遲,某種信號機制類型,以及更多,我敢肯定)。主要的是,永遠不會依賴或假定任務將在一定時間內完成。依賴時間可能會讓你感到很難受,而且很難調試。

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); 
    }; 
} 

但不知何故,的PhoneGap爲Android需要你聲明變量爲讀者的閱讀器的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

它需要用這種方式定義的原因是在設置onloadend偵聽器之前,您的讀取已經成功。 –

+0

是的,這很有道理。但奇怪的是,它在iOS中以其他方式正常工作。所以我猜猜這是關於每個瀏覽器解釋代碼和定義變量的順序。 – Pjottur