Idiom to close a cursor

后端 未结 7 1697
刺人心
刺人心 2021-02-08 03:57

Which of the following two should I be using to make sure that all the cursors are closed?

    Cursor c = getCursor(); 

    if(c!=null && c.getCount()&g         


        
相关标签:
7条回答
  • 2021-02-08 04:17

    Best practice is the one below:

    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.
    }
    
    0 讨论(0)
  • 2021-02-08 04:20

    I think @skylarsutton's is a right answer for the question. However, I want to leave codes for the question (any codes in answers seems to have some flaws). Please consider to use my code.

    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();
        }
    }
    
    0 讨论(0)
  • 2021-02-08 04:21

    This is even better:

    • does not use c.getCount() - counting might require extra work for the database and is not needed
    • initialize the cursor before the query block, so failure to create the query is not followed by the finally block

    The code:

    Cursor c = query(....);
    if (c != null) {
       try {        
           while (c.moveToNext()) {  // If empty or after last record it returns false.    
              // process row...
           }
       } 
       finally {
           c.close();
        }
    }
    

    Note that c might be null in case of error or empty cursor. See https://stackoverflow.com/a/16108435/952135. I would report null return value in case of empty cursor as a bug, though.

    0 讨论(0)
  • 2021-02-08 04:38

    Neither, but the second one was closest.

    • Option 1 doesn't properly close the Cursor when getCount() == 0
    • Option 2 leaves the finally block exposed to a null pointer exception

    I would use:

    Cursor c = getCursor(); 
    try { 
        if(c!=null && c.getCount()>0){ 
             // do stuff with the cursor
        }
    }
    catch(..) {
        //Handle ex
    }
    finally { 
        if(c != null) {
            c.close(); 
        }
    }
    

    ... or if you expect the cursor to be null frequently, you could turn it on its head a little bit:

    Cursor c = getCursor(); 
    if(c != null) {
        try { 
            if(c.getCount()>0) { 
                 // do stuff with the cursor
            }
        }
        catch(..) {
            //Handle ex
        }
        finally { 
            c.close(); 
        }
    }
    
    0 讨论(0)
  • 2021-02-08 04:38

    I think my answer is the best one :

        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;
            }
        }
    
    0 讨论(0)
  • 2021-02-08 04:42

    Depends on what you're catching, but I'd say the second one, just in case c.getCount() throws an exception.

    Also, some indentation wouldn't go amiss :)

    0 讨论(0)
提交回复
热议问题