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

Android Java中If-Else与Break语句的问题排查求助

解决Android文件读取中温度标识匹配的逻辑冲突问题

我明白你现在的困境——要么提前break导致错过目标标识,要么去掉break引发崩溃或重复提示。核心问题出在你在遍历文件行的过程中过早地执行了else逻辑,而不是等整个文件遍历完成后再统一判断是否找到标识。

先拆解下你的需求:

  1. 从SharedPreferences获取filename,遍历指定目录下的文件
  2. 在文件内容中找到匹配filename的行
  3. 若该文件中存在--TEMPERATURE UP--标识,就读取后续内容并发送指令
  4. 若不存在该标识,显示提示Toast

原代码的核心问题

  • 原代码在内部while循环中,每读一行如果不是目标标识就立刻弹Toast并break,这会导致文件还没读完就中断,即使后面有目标标识也找不到
  • 去掉break的话,会一直循环到文件结束,重复触发Toast提示,甚至因为未正确关闭资源或空指针导致崩溃
  • 你更新后的代码逻辑写反了:if (hasTempDisplayProfile)时弹Toast,这和需求完全相反,应该是没找到标识时才弹

修正后的完整代码

下面是调整后的代码,我加了详细注释,解决了所有逻辑问题和潜在的异常:

public void tempUp() {
    // 1. 获取目标filename,去除首尾空格避免匹配错误
    SharedPreferences sharedTest = getSharedPreferences("MySharedTest", Context.MODE_PRIVATE);
    String targetFilename = sharedTest.getString("filename", "").trim();
    Log.d("Target filename: ", targetFilename);

    // 2. 检查目标目录是否可访问
    File dir = new File(path);
    File[] files = dir.listFiles();
    if (files == null || files.length == 0) {
        Log.e("tempUp", "Directory is empty or inaccessible");
        Toast.makeText(TestScreen.this, "Failed to access profile directory", Toast.LENGTH_LONG).show();
        return;
    }

    boolean foundTargetFile = false;

    // 3. 遍历目录下的文件
    for (File f : files) {
        if (!f.isFile()) continue;

        BufferedReader inputStream = null;
        try {
            inputStream = new BufferedReader(new FileReader(f));
            String currentLine;
            boolean foundFilenameInFile = false;

            // 先检查当前文件是否包含目标filename行
            while ((currentLine = inputStream.readLine()) != null) {
                if (currentLine.trim().equals(targetFilename)) {
                    foundFilenameInFile = true;
                    foundTargetFile = true;
                    break; // 找到filename后停止读取当前文件的其他行
                }
            }

            // 4. 如果找到filename,继续查找温度标识
            if (foundFilenameInFile) {
                BufferedReader reader = new BufferedReader(new FileReader(f));
                String line;
                boolean hasTempUpFlag = false;
                String msValue = null;

                // 遍历文件查找--TEMPERATURE UP--
                while ((line = reader.readLine()) != null) {
                    if (line.equals("--TEMPERATURE UP--")) {
                        hasTempUpFlag = true;
                        msValue = reader.readLine(); // 读取标识后的参数行
                        break; // 找到标识后停止遍历
                    }
                }

                // 5. 遍历完成后统一判断逻辑
                if (hasTempUpFlag && msValue != null) {
                    Log.d("temp up: ", msValue);
                    // 启动子线程发送指令(避免阻塞UI)
                    new Thread(() -> {
                        String message = "\u000704NTX" + msValue + "\r";
                        byte[] byteArray = message.getBytes();
                        try {
                            SharedPreferences prefx = getSharedPreferences("Device_Data", Context.MODE_PRIVATE);
                            String deviceIp = prefx.getString("local_ip", "").trim();
                            if (deviceIp.isEmpty()) {
                                // 回到UI线程提示错误
                                runOnUiThread(() -> 
                                    Toast.makeText(TestScreen.this, "Device IP not configured", Toast.LENGTH_LONG).show()
                                );
                                return;
                            }
                            // 建立Socket连接并发送数据
                            Socket socket = new Socket(deviceIp, 8070);
                            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                            out.write(byteArray);
                            out.flush();
                            // 关闭资源,避免泄漏
                            out.close();
                            socket.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                            // 发送失败时回到UI线程提示
                            runOnUiThread(() -> 
                                Toast.makeText(TestScreen.this, "Failed to send temperature command", Toast.LENGTH_LONG).show()
                            );
                        }
                    }).start();
                } else {
                    // 未找到温度标识,显示提示
                    Toast.makeText(TestScreen.this, "There is no Temperature Display for this profile.", Toast.LENGTH_LONG).show();
                }

                reader.close(); // 关闭文件读取流
            }

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(TestScreen.this, "Failed to read profile file", Toast.LENGTH_LONG).show();
        } finally {
            // 确保资源被关闭,避免泄漏
            try {
                if (inputStream != null) inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 找到目标文件后停止遍历其他文件,提升效率
        if (foundTargetFile) break;
    }

    // 如果遍历完所有文件都没找到匹配的filename
    if (!foundTargetFile) {
        Toast.makeText(TestScreen.this, "Matching profile file not found", Toast.LENGTH_LONG).show();
    }
}

关键改进点

  1. 逻辑顺序调整:先确认文件包含目标filename,再查找温度标识,避免无效遍历
  2. 统一判断时机:等文件遍历完成后,再根据布尔变量hasTempUpFlag决定执行哪段逻辑,不会提前中断循环
  3. 资源泄漏修复:所有打开的流和Socket都被正确关闭
  4. 异常处理优化:增加了目录为空、IP未配置等边界情况的处理,且所有Toast都确保在UI线程执行(子线程中用runOnUiThread)
  5. 效率提升:找到目标文件后立刻停止遍历其他文件,减少不必要的IO操作

这样修改后,就不会出现之前的两难情况:找到标识时执行发送逻辑,没找到时显示提示,且不会崩溃。

内容的提问来源于stack exchange,提问作者Kelvin JigSawing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:53:24