成语关闭光标

时间:2010-11-10 12:15:28

标签: android sqlite cursor

我应该使用以下哪两项来确保所有游标都已关闭?

    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()。它假定对于没有元素的游标,永远不会打开游标。这是一个有效的假设吗?

请告知。

7 个答案:

答案 0 :(得分:13)

两者都没有,但第二个最接近。

  • 选项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 :(得分:3)

这更好:

  • 不使用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返回值。

答案 2 :(得分:1)

最佳做法如下:

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.
}

答案 3 :(得分:0)

取决于你捕获的内容,但我会说第二个,以防c.getCount()抛出异常。

另外,一些缩进不会出错:)

答案 4 :(得分:0)

我会说第一个,主要是因为即使c.close()c,第二个也会尝试拨打null。另外,根据文档,getCount()不会抛出任何异常,因此不需要将其包含在try块中。

答案 5 :(得分:-1)

我认为我的答案是最好的答案:

    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;
        }
    }

答案 6 :(得分:-1)

我认为@ 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();
    }
}