Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java StrictMode抱怨InputStream未关闭_Java_Android_Objectinputstream_Android Strictmode - Fatal编程技术网

Java StrictMode抱怨InputStream未关闭

Java StrictMode抱怨InputStream未关闭,java,android,objectinputstream,android-strictmode,Java,Android,Objectinputstream,Android Strictmode,我收到Android中的以下违规报告 02-05 04:07:41.190:错误/严格模式(15093):已获取资源 在附加的堆栈跟踪,但从未释放。有关详细信息,请参见java.io.Closeable 关于避免资源泄漏的信息。02-05 04:07:41.190: 错误/StrictMode(15093):java.lang.Throwable:显式终止 未调用方法“close” 它是在嘲笑没有正确关闭数据流。但是,在中关闭是否应该关闭底层流?标记错误的原因可能是什么 private

我收到Android中的以下违规报告

02-05 04:07:41.190:错误/严格模式(15093):已获取资源 在附加的堆栈跟踪,但从未释放。有关详细信息,请参见java.io.Closeable 关于避免资源泄漏的信息。02-05 04:07:41.190: 错误/StrictMode(15093):java.lang.Throwable:显式终止 未调用方法“close”

它是在嘲笑没有正确关闭数据流。但是,在中关闭
是否应该关闭底层流?标记错误的原因可能是什么

    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
        }
    }
private ArrayList loadPath(){
ArrayList URI=新的ArrayList();
if(mFile.exists()){
ObjectInputStream in=null;
试一试{
in=新对象输入流(新的BufferedInputStream(
新文件输入流(mFile),流(缓冲区大小);
ArrayList字符串=新的ArrayList();
.readObject()中的strings.addAll((ArrayList);
for(字符串:字符串){
add(Uri.parse(string));
}
}捕获(例外e){
mFile.delete();
}最后{
安静地关闭(在);
}
}
返回URI;
}
公共静态输入(InputStream输入){
试一试{
如果(输入!=null){
input.close();
}
}捕获(ioe异常ioe){
//忽略
}
}

如果查看ObjectOutpuStream源代码,您将看到其close方法关闭底层流。Android的严格模式和许多其他代码分析工具一样存在误报,您可以忽略或重写代码,使其不会抱怨(内联关闭方法)。

除非您使用的是ProGuard,它可能会对字节码造成一点麻烦,否则代码应该可以工作

FileInputStream
具有到
CloseGuard
的钩子,如果实例已关闭,则会在finalize()中选中该钩子。这就是我认为它应该起作用的原因。问题是是否调用了天气
close()

我认为
FileInputStream
是创建的(因为StrictMode引发了异常),但最后抛出了一个异常,并在某个地方被忽略

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

查看源代码,两个和的构造函数都可以抛出异常,这将导致在下一行分配
FileInputStream
对象,但
中的
变量仍然为null:

            in = new ObjectInputStream(
                    new BufferedInputStream(
                            new FileInputStream(mFile), 
                    STREAM_BUFFER_SIZE)
            );
由于当我们到达
finally
块时,
in
中的
为空,因此打开的
FileInputStream
对象将不会被
closequitley()关闭(
方法关闭,导致
stricmode
最终抱怨:)

我建议的最简单的修复方法是将该分配拆分为3个变量,并在每个变量上调用
closequity()
,可能类似这样:

private ArrayList<Uri> loadPath() {
    final ArrayList<Uri> uris = new ArrayList<Uri>();
    if (mFile.exists()) {
        ObjectInputStream ois = null;
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            fis = new FileInputStream(mFile);
            bis = new BufferedInputStream(fis, STREAM_BUFFER_SIZE);
            ois = new ObjectInputStream(bis);
            final ArrayList<String> strings = new ArrayList<String>();
            strings.addAll((ArrayList<String>) ois.readObject());
            for (final String string : strings) {
                uris.add(Uri.parse(string));
            }
        } catch (final Exception e) {
            mFile.delete();
        } finally {
            closeQuietly(fis);
            closeQuietly(bis);
            closeQuietly(ois);
        }
    }
    return uris;
}
private ArrayList loadPath(){
最终ArrayList URI=新ArrayList();
if(mFile.exists()){
ObjectInputStream ois=null;
FileInputStream fis=null;
BufferedInputStream bis=null;
试一试{
fis=新文件输入流(mFile);
bis=新的BufferedInputStream(fis,流\缓冲区\大小);
ois=新的ObjectInputStream(bis);
最终ArrayList字符串=新ArrayList();
strings.addAll((ArrayList)ois.readObject());
for(最终字符串:字符串){
add(Uri.parse(string));
}
}捕获(最终异常e){
mFile.delete();
}最后{
关闭(fis);
国际清算银行(bis);
(ois);
}
}
返回URI;
}
在此代码示例中,您只关闭
ObjectInputStream
,而不关闭
BufferedInputStream

或者
FileInputStream
,您需要全部关闭它们。

不确定StrictMode检查器有多智能,但它似乎被延迟关闭(即使用实用程序为您关闭流)弄糊涂了。在我的情况下,即使
close()
内嵌在
finally
子句中。Android的StrictMode不是代码分析工具。它是在源代码中实现的查看
FileInputStream
CloseGuard
中的
finalize()
。很好地发现了这一点,但在我的例子中没有发生异常。(我会回去仔细检查一下,以确保绝对正确。)也许我错了,但你不也会抱怨“可能的情况”吗?例如,它抱怨来自主线程的IO访问,即使没有实际导致ANR。它应该抱怨实际发生的事情。在主线程上进行IO访问的情况下,主线程上确实发生了IO访问。(这不仅仅是理论上的。)因此,如果InputStream真的泄漏了,它应该只抱怨InputStream泄漏。如果你在OP的代码中发现了可能导致泄漏的真正问题,你就会得到赏金。我不是OP,我自己的代码非常相似,但有细微的不同,我仍然需要彻底了解它。谢谢!如果您也希望帮助您找出代码中的问题,那么从这里添加一个链接很可能会添加几组新的眼睛来查看它:)您呢?这与康斯坦丁·索洛马托夫的回答相矛盾。@GrahamBorland只需对其进行测试,您就会看到。
in = new ObjectInputStream(new BufferedInputStream(
                         new FileInputStream(mFile), STREAM_BUFFER_SIZE));