我应该使用以下哪两个来确保所有游标都关闭?
Cursor c = getCursor();
if(c!=null && c.getCount()>0){
try{
// read values from cursor
}catch(..){}
finally{
c.close();
}
}//end if
OR
Cursor c = getCursor();
try{
if(c!=null && c.getCount()>0){
// read values from cursor
}//end if
}catch(..){
}finally{
c.close();
}
编辑:
几个问题:
1.我们是否需要在计数为0的游标上调用close()?
因为在第一个习语的情况下,将永远不会调用close()。它假定对于没有元素的游标,永远不会打开游标。这是一个有效的假设吗?
请指教。
两者都没有,但第二个是最接近的。
- 选项1没有正确关闭
getCount()== 0时的游标
- 选项2使finally块暴露于空指针异常
我会用:
Cursor c = getCursor();
try {
if(c!=null && c.getCount()>0){
// do stuff with the cursor
}
}
catch(..) {
//Handle ex
}
finally {
if(c != null) {
c.close();
}
}
...或者如果您希望光标经常为空,您可以稍微转过头:
Cursor c = getCursor();
if(c != null) {
try {
if(c.getCount()>0) {
// do stuff with the cursor
}
}
catch(..) {
//Handle ex
}
finally {
c.close();
}
}
两者都没有,但第二个是最接近的。
- 选项1没有正确关闭
getCount()== 0时的游标
- 选项2使finally块暴露于空指针异常
我会用:
Cursor c = getCursor();
try {
if(c!=null && c.getCount()>0){
// do stuff with the cursor
}
}
catch(..) {
//Handle ex
}
finally {
if(c != null) {
c.close();
}
}
...或者如果您希望光标经常为空,您可以稍微转过头:
Cursor c = getCursor();
if(c != null) {
try {
if(c.getCount()>0) {
// do stuff with the cursor
}
}
catch(..) {
//Handle ex
}
finally {
c.close();
}
}
这甚至更好:
- 不使用c.getCount() - 计数可能需要额外的数据库工作,不需要
- 在查询块之前初始化游标,因此创建查询失败后不会跟随finally块
代码:
Cursor c = query(....);
if (c != null) {
try {
while (c.moveToNext()) { // If empty or after last record it returns false.
// process row...
}
}
finally {
c.close();
}
}
注意 c
如果出现错误或空光标,则可能为null。看到 https://stackoverflow.com/a/16108435/952135。但是,如果将空光标作为错误,我会报告null返回值。
最佳做法如下:
Cursor c = null;
try {
c = query(....);
while (c.moveToNext()) { // If empty or next to last record it returns false.
// do stuff..
}
} finally {
if (c != null && !c.isClosed()) { // If cursor is empty even though should close it.
c.close();
c = null; // high chances of quick memory release.
}
取决于你捕获的是什么,但我会说第二个,以防万一 c.getCount()
抛出一个例外。
另外,一些缩进不会有问题:)
我会说第一个,主要是因为第二个会试着打电话 c.close()
即使 c
是 null
。另外,根据文档, getCount()
不会抛出任何异常,因此不需要将其包含在内 try
块。
我认为我的答案是最好的答案:
Cursor cursor = null;
try {
cursor = rsd.rawQuery(querySql, null);
if (cursor.moveToFirst()) {
do {
// select your need data from database
} while (cursor.moveToNext());
}
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
cursor = null;
}
}
我认为@ skylarsutton是这个问题的正确答案。但是,我想留下问题的代码(答案中的任何代码似乎都有一些缺陷)。请考虑使用我的代码。
Cursor c = query(....);
if (c != null) {
try {
//You have to use moveToFirst(). There is no quarantee that a cursor is located at the beginning.
for(c.moveToFirst();!c.isAfterLast();c.moveToNext()) {
// process row...
}
}
finally {
c.close();
}
}