我在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
}
}
答案 0 :(得分:10)
查看源代码,ObjectInputStream
和BufferedInputStream
的构造函数都可以抛出异常,这会导致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可能会破坏字节码。
FileInputStream
与CloseGuard
挂钩,如果实例已关闭,则会在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
,但不关闭BufferedInputStream
或FileInputStream
,你需要关闭它们。