I'm getting the following violation reported by StrictMode in Android.
02-05 04:07:41.190: ERROR/StrictMode(15093): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. 02-05 04:07:41.190: ERROR/StrictMode(15093): java.lang.Throwable: Explicit termination method 'close' not called
It is cribbing about not closing streams properly. However, shouldn't closing in
close the underlying streams? What could be the reason for the flagged error?
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
}
}
Looking at the source code, the constructors for both ObjectInputStream
and BufferedInputStream
can throw exceptions which would cause a FileInputStream
object to be allocated on the following line, but the in
variable will still be null:
in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(mFile),
STREAM_BUFFER_SIZE)
);
Since in
is null when we get to the finally
block, that open FileInputStream
object will not be closed by your closeQuietly()
method, causing StrictMode
to complain eventually :)
The simplest fix I would suggest is to split that allocation into 3 variables and call closeQuietly()
on each, maybe something like this:
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;
}