0

这是我目前的情况:
Eclipse
Win7
Samsung SII(用于测试)

我正在编写一个应用程序,它将在启动时从设备上私有存储的文件中读取,然后,我想在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

马特

4

4 回答 4

3

你应该阅读 onDestroy 的文档。你应该使用 onPause 代替。阅读下文了解更多详情

不要指望 this(onDestroy()) 方法被称为保存数据的地方!例如,如果一个活动在内容提供者中编辑数据,这些编辑应该在 onPause() 或 onSaveInstanceState(Bundle) 中提交,

protected void onDestroy ()
Since: API Level 1

在销毁活动之前执行任何最终清理。这可能是因为 Activity 正在完成(有人在其上调用了 finish(),或者因为系统正在临时销毁该 Activity 实例以节省空间。您可以使用 isFinishing() 方法区分这两种情况。

注意:不要指望这个方法被称为保存数据的地方!例如,如果一个活动正在内容提供者中编辑数据,那么这些编辑应该在 onPause() 或 onSaveInstanceState(Bundle) 中提交,而不是在这里。此方法通常用于释放资源,例如与活动相关联的线程,以便被破坏的活动不会在其应用程序的其余部分仍在运行时留下这些东西。在某些情况下,系统会简单地终止 Activity 的宿主进程,而不会在其中调用此方法(或任何其他方法),因此不应使用它来执行打算在进程消失后保留的事情。派生类必须调用该方法的超类实现。如果他们不这样做,将引发异常。

参考链接:- Android onDestroy

于 2012-08-08T06:10:38.770 回答
1

我认为您对数据存储的选择给您带来的问题超出了它的价值。我不知道有多少情况依赖于即将到来的流程来管理数据流。

通过您的变量名,也许 SharedPreferences 是一个更合适的数据结构? http://developer.android.com/reference/android/content/SharedPreferences.html

如果您坚持使用平面文件,那么我认为您仍然应该使用 contentprovider 管理数据存储。

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

现在 tute 确实使用了 sqlite 支持的内容提供程序。但是无论如何您都可以使用平面文件。

无论如何,应用程序崩溃的原因是与数据流时间不同的问题。

于 2012-08-08T06:09:19.327 回答
0

PorkAnkit所说的一切。此外,不要在主 (UI) 线程上执行文件 I/O!除非你坚持大量的信息,否则我认为SharedPreferences是要走的路。它非常适合存储重新创建应用程序状态所需的几十个奇数值。

于 2012-08-08T06:18:25.013 回答
0

查看此处的文档,似乎没有onDestroy适用于 Application 类的方法,因此这似乎使该想法在那里无法实现。

我不知道您为什么要尝试重新发明轮子,但我会放弃它并使用其他所有人都在使用的标准做法……它们是标准做法是有原因的。:p

于 2012-08-08T06:34:02.637 回答