You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio内部存储变量存读问题:加载按钮崩溃求助

问题描述

点击保存按钮将数据保存至MovingAndMoreAppData.txt,点击加载按钮读取数据时应用崩溃。目前仅能触发按钮点击事件,保存代码无法验证,尝试多种加载方式均无效。

相关代码

保存按钮逻辑

else if (xID == R.id.saveJobButton) {
    try {
        //to save data to a file
        FileOutputStream xFileOutput = openFileOutput("MovingAndMoreAppData.txt", MODE_PRIVATE);
        OutputStreamWriter xOutputWriter = new OutputStreamWriter(xFileOutput);

        xOutputWriter.write(
                xStartMiles);   //integer variable from a EditText view
        
        //TODO after get xStartMiles working
                /*xStartTime + "," +
                        xEndTime + "," +
                        xEndDriveCounter + "," +
                        xStartDriveCounter + "," +
                        xEndMiles + "," +
                        xTotalMiles + "," +
                        xDriveTime1 + "," +
                        xDriveTime2 + "," +
                        xDriveTime3 + "," +
                        xDriveTime4 + "," +
                        xDriveTime5 + "," +
                        xDriveTimeTotal + "," +
                        xEndDriveTime1 + "," +
                        xEndDriveTime2 + "," +
                        xEndDriveTime3 + "," +
                        xEndDriveTime4 + "," +
                        xEndDriveTime5 + "," +
                        xStartDriveTime1 + "," +
                        xStartDriveTime2 + "," +
                        xStartDriveTime3 + "," +
                        xStartDriveTime4 + "," +
                        xStartDriveTime5 + "," +
                        xTotalTime);

                  */

        xOutputWriter.flush();
        xOutputWriter.close();

        Toast.makeText(TimeLogActivity.this, "Data Saved", Toast.LENGTH_SHORT).show();
    }
    catch (IOException e) {
        Toast.makeText(TimeLogActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }

}

加载按钮逻辑

//to load data from file
else if (xID == R.id.loadJobButton) {

    Toast.makeText(TimeLogActivity.this, "button pressed", Toast.LENGTH_SHORT).show();
    //need line below when loading data so it can display it
    //xStartMilesInput.setText(String.valueOf(50));


    File xFileToRead = getApplicationContext().getFileStreamPath("MovingAndMoreAppData.txt");
    String lineFromFile;

    if(xFileToRead.exists()) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(openFileInput("MovingAndMoreAppData.txt")));

            while((lineFromFile = reader.readLine()) != null) {
                StringTokenizer tokens = new StringTokenizer(lineFromFile, ",");
                xStartMiles = Integer.parseInt(tokens.nextToken());

                //set the EditText view to the integer value of the saved xStartMiles
                xStartMilesInput.setText(String.valueOf(xStartMiles));


            }

            reader.close();

        } catch (IOException e) {
            Toast.makeText(TimeLogActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }


}

LogCat错误日志

2023-12-13 11:56:51.855 19740-19740 AndroidRuntime        com...andmoving404.movingandmoreapp  E  FATAL EXCEPTION: main                                                                                            
Process: com.moreandmoving404.movingandmoreapp, PID: 19740                                                                              
java.lang.NumberFormatException: For input string: "??"                                                                                
at java.lang.Integer.parseInt(Integer.java:604)                                                                                      
at java.lang.Integer.parseInt(Integer.java:650)                                                                                      
at com.moreandmoving404.movingandmoreapp.TimeLogActivity.onClick(TimeLogActivity.java:311)
                                                                                            
at android.view.View.performClick(View.java:7441)                                                                                                
at android.view.View.performClickInternal(View.java:7418)                                                                                                        
at android.view.View.access$3700(View.java:835)                                                                                                      
at android.view.View$PerformClick.run(View.java:28676)                                                                                                       
at android.os.Handler.handleCallback(Handler.java:938)                                                                                                       
at android.os.Handler.dispatchMessage(Handler.java:99)                                                                                                       
at android.os.Looper.loopOnce(Looper.java:201)                                                                                                       
at android.os.Looper.loop(Looper.java:288)                                                                                                       
at android.app.ActivityThread.main(ActivityThread.java:7839)                                                                                                         
at java.lang.reflect.Method.invoke(Native Method)                                                                                                        
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
                                                                                                         
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
2023-12-13 11:56:57.449 19740-19753 System                  com...andmoving404.movingandmoreapp  W  A resource failed to call close. 
问题分析与修复方案

核心问题

加载崩溃的直接原因是NumberFormatException,说明读取到的字符串无法转为整数。根源出在保存代码:

  • xOutputWriter.write(xStartMiles)调用的是Writer.write(int c)方法,这个方法会把整数当作ASCII码写入字符,而非写入数字的字符串形式。比如xStartMiles=123会被写成ASCII码对应的字符{,如果是其他数字可能生成乱码,导致读取时得到"??"这类无法解析的内容。

修复步骤

1. 修正保存代码

把整数转为字符串后再写入,同时为后续多数据保存预留分隔符(比如换行或逗号):

else if (xID == R.id.saveJobButton) {
    try {
        FileOutputStream xFileOutput = openFileOutput("MovingAndMoreAppData.txt", MODE_PRIVATE);
        OutputStreamWriter xOutputWriter = new OutputStreamWriter(xFileOutput);
        // 将整数转为字符串写入,加上换行符方便逐行读取
        xOutputWriter.write(String.valueOf(xStartMiles) + "\n");
        
        // 后续多数据保存时可以用逗号分隔,例如:
        // xOutputWriter.write(xStartMiles + "," + xStartTime + "," + xEndTime + "\n");
        
        xOutputWriter.flush();
        xOutputWriter.close();
        Toast.makeText(TimeLogActivity.this, "Data Saved", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        Toast.makeText(TimeLogActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }
}

2. 优化加载代码

  • 添加异常处理,避免因解析失败或数据格式错误导致崩溃
  • 使用try-with-resources自动关闭流,避免资源泄漏
  • 增加Token存在性判断,防止NoSuchElementException
else if (xID == R.id.loadJobButton) {
    Toast.makeText(TimeLogActivity.this, "button pressed", Toast.LENGTH_SHORT).show();
    File xFileToRead = getApplicationContext().getFileStreamPath("MovingAndMoreAppData.txt");
    if(xFileToRead.exists()) {
        // 使用try-with-resources自动关闭BufferedReader
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(openFileInput("MovingAndMoreAppData.txt")))) {
            String lineFromFile;
            while((lineFromFile = reader.readLine()) != null) {
                // 先修剪字符串,去除空格和换行符
                lineFromFile = lineFromFile.trim();
                if(lineFromFile.isEmpty()) continue;
                
                StringTokenizer tokens = new StringTokenizer(lineFromFile, ",");
                // 先判断是否有可用的Token
                if(tokens.hasMoreTokens()){
                    try {
                        xStartMiles = Integer.parseInt(tokens.nextToken().trim());
                        xStartMilesInput.setText(String.valueOf(xStartMiles));
                    } catch (NumberFormatException e) {
                        Toast.makeText(TimeLogActivity.this, "数据格式错误:" + e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                }
            }
        } catch (IOException e) {
            Toast.makeText(TimeLogActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(TimeLogActivity.this, "数据文件不存在", Toast.LENGTH_SHORT).show();
    }
}

后续扩展建议

当需要保存多组数据时,建议:

  • 每条数据占一行,用逗号分隔各个字段
  • 读取时按行解析,逐个字段转换类型
  • 可以考虑使用JSON格式保存数据,比纯字符串分隔更易维护(比如用Gson库序列化对象)

内容的提问来源于stack exchange,提问作者Rob H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:54:52