2012-08-08 86 views
0

這是我目前的情況:
Eclipse的
Win7的
三星SII(用於測試)安卓:寫入文件的OnDestroy()

我寫將從設備上私自存儲在文件中讀取的應用當它啓動時,然後,我想要在應用程序的onDestroy()被調用時寫入相同的文件(基本覆蓋)。

我首先嚐試用我自己的類擴展應用程序,然後讀取和寫入該文件的構造函數並銷燬該類,但是,該類中的讀取或寫入似乎不被允許作爲我的應用程序每次啓動時都會崩潰。所以我想了一會兒,然後自己在主菜單上做了這件事,因爲這是我唯一不需要的活動,不是"destroy" (or ActivityName.this.finish();)。但我的程序員的大腦想要在應用程序級別實現這一點,而不是活動級別。

那麼,我有可能從我創建的Application類構造函數中的文件中讀取,然後寫入onDestroy()中的文件?如果是這樣,怎麼樣?我的應用程序只是不斷崩潰/甚至不會啓動...

這是我使用的代碼。這有效地讀取一個文件,並將一些字符串存儲到全局內存中(請注意「不,不」)請全局變量對我非常有用),然後使用全局變量中的值調用onDestroy()時覆蓋文件瓦爾(我知道這一點,因爲它工作在活動水平):現在

CONSTRUCTOR: 
super(); 

    try 
    { 
     String origprefs =",0,1-1"; 

     File f = new File(this.getFilesDir(),FILENAME); 

     if(!f.exists()) 
     { 
      FileOutputStream fos2 = new FileOutputStream(f); 
      fos2.write(origprefs.getBytes()); 
      fos2.close(); 
     } 

     FileInputStream fis; 
     fis = openFileInput(FILENAME); 
     StringBuffer fileContent = new StringBuffer(""); 

     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = fis.read(buffer)) != -1) { 
      fileContent.append(new String(buffer)); 
     } 
     fis.close(); 

     origprefs = fileContent.toString(); 

     //set our globals 
     Username = origprefs.split(",")[0]; 
     Score = origprefs.split(",")[1]; 
     Stage = origprefs.split(",")[2]; 

    } 
    catch (IOException e) 
    { 
     throw new RuntimeException("Unable to either Read or Write to Match Two file."); 
    } 

onDestroy: 
if(GameRunning) 
    { 
     try 
     { 
      FileOutputStream fis; 
       fis = openFileOutput(FILENAME, this.MODE_PRIVATE); 
       String fileContent = Username + "," + Score + "," + Stage; 
       fis.write(fileContent.getBytes()); 
       fis.close(); 
     } 
     catch(IOException e) 
     { 
      throw new RuntimeException("Unable to either Read or Write to Match Two file."); 
     } 
    } 

,這是相同的過程中,減去了一些改建,以獲得適當的情況下,MainMenu的類中。當我在應用程序級別執行操作時,我無法將自己的頭包裹起來,爲什麼會使我的應用程序崩潰?謝謝你的幫助!

這裏的logcat的條目 logcat的是神祕的我覺得......

08-08 02:03:58.362: E/AndroidRuntime(10360): FATAL EXCEPTION: main 
08-08 02:03:58.362: E/AndroidRuntime(10360): java.lang.RuntimeException: Unable to instantiate application maxovrdrv.FirstApp.MatchTwo: java.lang.NullPointerException 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.LoadedApk.makeApplication(LoadedApk.java:466) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3268) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.ActivityThread.access$2200(ActivityThread.java:117) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:973) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.os.Handler.dispatchMessage(Handler.java:99) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.os.Looper.loop(Looper.java:130) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.ActivityThread.main(ActivityThread.java:3691) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at java.lang.reflect.Method.invokeNative(Native Method) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at java.lang.reflect.Method.invoke(Method.java:507) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at dalvik.system.NativeStart.main(Native Method) 
08-08 02:03:58.362: E/AndroidRuntime(10360): Caused by: java.lang.NullPointerException 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.content.ContextWrapper.getFilesDir(ContextWrapper.java:178) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at maxovrdrv.FirstApp.MatchTwo.<init>(MatchTwo.java:26) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at java.lang.Class.newInstanceImpl(Native Method) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at java.lang.Class.newInstance(Class.java:1409) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.Instrumentation.newApplication(Instrumentation.java:957) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.Instrumentation.newApplication(Instrumentation.java:942) 
08-08 02:03:58.362: E/AndroidRuntime(10360): at android.app.LoadedApk.makeApplication(LoadedApk.java:461) 
08-08 02:03:58.362: E/AndroidRuntime(10360): ... 11 more 

馬特

+0

發佈logcat輸出也如果它的崩潰 – nandeesh 2012-08-08 05:54:21

+0

logcat是神祕的我發現... – MaxOvrdrv 2012-08-08 06:04:46

+0

請不要使用StringBuffer時,你可以使用StringBuilder。 – 2012-08-13 08:09:18

回答

3

你應該閱讀onDestroy文檔..你應該使用onPause代替。閱讀下面的更多細節

不要指望這個(onDestroy())方法被稱爲保存數據的地方!例如,如果一個活動是在內容提供商編輯數據,這些編輯應在任一的onPause()或的onSaveInstanceState(束)提交,

protected void onDestroy() 
Since: API Level 1 

前一個活動是執行任何最後的清理銷燬。這可能是因爲活動正在完成(有人稱爲finish(),或者系統暫時銷燬此活動的實例以節省空間。您可以使用isFinishing()方法區分這兩種情況。

注意:不要指望這種方法被稱爲保存數據的地方!例如,如果一個活動正在編輯內容提供者中的數據,那麼這些編輯應該在onPause()或onSaveInstanceState(Bundle)中提交,而不是這個方法通常被實現來釋放資源,例如與活動相關聯的線程,這樣一來,被破壞的活動就不會離開這些東西,而其餘的應用程序仍然在運行,有些情況下系統會簡單地殺死活動的託管過程,而無需調用此方法(或任何其他方法),因此它不應該被使用d在流程結束後做一些有意留下來的事情。 派生類必須調用超類的這種方法的實現。如果他們不這樣做,就會拋出異常。

參考鏈接: - Android onDestroy

+0

這很好,但同樣,我沒有試圖在活動層面做到這一點,但在應用層面。我相信應用程序的onDestroy只有在應用程序死亡時纔會被調用。當你自己關閉它時應該是這樣。 – MaxOvrdrv 2012-08-08 06:21:27

+1

謝謝。我使用onPause,但必須將其保留在Activity中,而不是Application中。不是我真正想要的,但它沒有任何問題,每當用戶離開應用程序時都會被解僱。只希望有一種方法可以在全局/應用程序級而不是在活動中執行此操作。然而,我重新調整了我的代碼,只使用一個活動來管理遊戲的生命週期(例如:級別級數和屏幕更改全部在MainActivity類中完成...),以便應該工作...我猜... – MaxOvrdrv 2012-08-08 20:12:56

+0

的事情是,你不應該做單一活動的所有屏幕更改。建議使用主屏幕,並讓用戶每次想要退出應用程序時都進入該屏幕 – AAnkit 2012-08-09 05:33:38

1

我覺得你的選擇數據存儲的是造成你更多的問題比它的價值。我不知道有多少依賴於流程來處理數據流的流程。

通過你的變量名或許SharedPreferences是一個更合適的數據結構? http://developer.android.com/reference/android/content/SharedPreferences.html

如果你堅持一個平面文件,那麼我認爲你應該仍然使用contentprovider管理數據存儲。

http://www.vogella.com/articles/AndroidSQLite/article.html

現在土特確實使用的SQLite支持的內容提供商。但是無論如何你可以使用一個平面文件。

無論如何,爲什麼該應用程序崩潰是一個單獨的問題,從數據流的時間。

0

一切PorkAnkit說。此外,不要在主(UI)線程上執行文件I/O!除非你堅持大量的信息,否則我認爲SharedPreferences是要走的路。它非常適合存儲您需要重新創建應用程序狀態的幾十個奇數值。

0

查看文檔here,應用程序類看起來沒有onDestroy方法,因此似乎使該想法成爲非起始者。

我不知道你爲什麼試圖重新發明輪子,但我會放棄它,並使用其他人正在使用的標準實踐......這是他們是標準實踐的原因。 :p