StrictMode抱怨InputStream未被关闭

时间:2012-03-01 11:37:00

标签: java android objectinputstream android-strictmode

我在Android中StrictMode报告了以下违规行为。

  

02-05 04:07:41.190:ERROR / StrictMode(15093):获取资源   附加堆栈跟踪但从未发布。请参阅java.io.Closeable   有关避免资源泄漏的信息。 02-05 04:07:41.190:   ERROR / StrictMode(15093):java.lang.Throwable:显式终止   方法'close'未调用

关于不正确关闭溪流的问题。但是,不应该关闭in关闭底层流吗?可能是标记错误的原因是什么?

    private ArrayList<Uri> loadPath() {
        ArrayList<Uri> uris = new ArrayList<Uri>();
        if (mFile.exists()) {
            ObjectInputStream in = null;
            try {
                in = new ObjectInputStream(new BufferedInputStream(
                         new FileInputStream(mFile), STREAM_BUFFER_SIZE));
                ArrayList<String> strings = new ArrayList<String>();
                strings.addAll((ArrayList<String>) in.readObject());
                for (String string : strings) {
                    uris.add(Uri.parse(string));
                }
            } catch (Exception e) {
                mFile.delete();
            } finally {
                IOUtils.closeQuietly(in);
            }
        }
        return uris;
     }

    public static void closeQuietly(InputStream input) {
        try {
            if (input != null) {
                input.close();
            }
        } catch (IOException ioe) {
            // ignore
        }
    }

4 个答案:

答案 0 :(得分:10)

查看源代码,ObjectInputStreamBufferedInputStream的构造函数都可以抛出异常,这会导致FileInputStream对象在下一行分配,但是{{1变量仍为null:

in

当我们到达 in = new ObjectInputStream( new BufferedInputStream( new FileInputStream(mFile), STREAM_BUFFER_SIZE) ); 块时,in为空,因此finally方法不会关闭该FileInputStream个对象,从而导致closeQuietly()最终抱怨:)

我建议最简单的解决方法是将该分配分成3个变量并在每个变量上调用StrictMode,可能是这样的:

closeQuietly()

答案 1 :(得分:0)

如果你看看ObjectOutpuStream源代码,你会发现它的close方法关闭了底层流。像许多其他代码分析工具一样,Android的严格模式有误报,你可以忽略或重写代码,这样它就不会抱怨(内联closeQuietly方法)。

答案 2 :(得分:0)

代码应该可以工作,除非你使用的ProGuard可能会破坏字节码。

FileInputStreamCloseGuard挂钩,如果实例已关闭,则会在finalize()中检查。这就是我认为应该有效的原因。问题是天气close()是否被调用?

我认为FileInputStream已创建(因为StrictMode抛出了异常),但最终抛出了一个异常而忽略了某个地方。

    try {
        if (input != null) {
            input.close();
        }
    } catch (Exception ioe) {
        // check exception here
    }

答案 3 :(得分:0)

in = new ObjectInputStream(new BufferedInputStream(
                         new FileInputStream(mFile), STREAM_BUFFER_SIZE));

在此代码示例中,您只关闭ObjectInputStream,但不关闭BufferedInputStreamFileInputStream,你需要关闭它们。