Hi,

In the past few months I've been learning how to make applications for android by making small games just for the fun of it. I am stuck at the moment at the database object I created to manage the database, specifically the cursor: it won't close. A snippet of my code:

public class DatabaseManager extends Activity
{
	// the Activity or Application that is creating an object from this class.
	Context context;
 
	// a reference to the database used by this application/object
	private SQLiteDatabase db;

/**********************************************************************
	 * RETRIEVING A ROW FROM THE DATABASE TABLE
	 * 
	 * This is an example of how to retrieve a row from a database table
	 * using this class.  You should edit this method to suit your needs.
	 * 
	 * @param rowID the id of the row to retrieve
	 * @return an array containing the data from the row
	 */
	public ArrayList<Object> getRowAsArray(long rowID)
	{
		// create an array list to store data from the database row.
		// I would recommend creating a JavaBean compliant object 
		// to store this data instead.  That way you can ensure
		// data types are correct.
		ArrayList<Object> rowArray = new ArrayList<Object>();
 
		try
		{
			
			Cursor cursor;
			
			// this is a database call that creates a "cursor" object.
			// the cursor object store the information collected from the
			// database and is used to iterate through the data.
			cursor = db.query
			(
					TABLE_NAME,
					new String[] { TABLE_ROW_ID, TABLE_ROW_ONE },
					TABLE_ROW_ID + "=" + rowID,
					null, null, null, null, null
			);
			
			startManagingCursor(cursor);
			
			// move the pointer to position zero in the cursor.
			cursor.moveToFirst();
 
			// if there is data available after the cursor's pointer, add
			// it to the ArrayList that will be returned by the method.
			if (!cursor.isAfterLast())
			{
				do
				{
					rowArray.add(cursor.getLong(0));
					rowArray.add(cursor.getLong(1));
				}
				while (cursor.moveToNext());
			}
 
			// let java know that you are through with the cursor.
			cursor.close();
		}
		catch (SQLException e) 
		{
			Log.e("DB ERROR", e.toString());
			e.printStackTrace();
		}

		// return the ArrayList containing the given row from the database.
		return rowArray;
	}

}

I keep getting the error after some time each time that function is called:

10-02 16:07:23.618: WARN/SQLiteCompiledSql(3945): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: UPDATE nw_table SET value=?, id=? WHERE id=9
10-02 16:07:23.618: WARN/SQLiteCompiledSql(3945): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

And then resulting in a database crash:

10-02 16:07:23.748: ERROR/Database(3945): close() was never explicitly called on database '/data/data/com.deltac.neonwars/databases/database_neon_wars' 
10-02 16:07:23.748: ERROR/Database(3945): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

Does anyone know how I can fix this?

Thanks in advance,
~G

Hi,

I've finally found the solution to the database problem: I forgot to close the database when the parent activity was finished ( db.close(); ). But I experiencing a new problem: the MediaPlayer is being stopped GC_FOR_MALLOC. The output of LogCat (I highlighted the lines that I think matter):

10-02 19:10:05.968: DEBUG/dalvikvm(453): GC_EXPLICIT freed 7712 objects / 428800 bytes in 844ms
10-02 19:10:07.328: VERBOSE/MediaPlayerService(67): disconnect(36) from pid 6011
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset (382)
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset_l (388)
10-02 19:10:07.328: WARN/TimedEventQueue(67): Event 300 was not found in the queue, already cancelled?
10-02 19:10:07.328: VERBOSE/AudioSink(67): stop
10-02 19:10:07.328: VERBOSE/AudioSink(67): close
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset_l (478)
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset (382)
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset_l (388)
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset_l (478)
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset (382)
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset_l (388)
10-02 19:10:07.328: DEBUG/AwesomePlayer(67): [U5B] reset_l (478)
[B]10-02 19:10:07.328: VERBOSE/MediaPlayerService(67): Client(36) destructor pid = 6011
10-02 19:10:07.328: VERBOSE/AudioSink(67): close
10-02 19:10:07.328: VERBOSE/MediaPlayerService(67): disconnect(36) from pid 6011
10-02 19:10:07.328: DEBUG/dalvikvm(6011): GC_FOR_MALLOC freed 52277 objects / 2056488 bytes in 62ms[/B]
10-02 19:10:10.378: INFO/AudioHardwareQSD(67): AudioHardware pcm playback is going to standby.

This is the function I use to play music:

/**
         * Plays an in-game sound effects
         * 
         * @param res_id : The raw resource to be played (.mp3, .wav etc.) e.g. R.raw.explosion_small
         * @param loop : Boolean that indicates whether it needs to be looped
         *
        */
        private void playSound( int res_id, boolean loop ) {
 
	       MediaPlayer mp = MediaPlayer.create(mContext, res_id);   
	       mp.setLooping(loop);
	       mp.start();
	
	       mp.setOnCompletionListener(new OnCompletionListener() {
	
	             @Override
	             public void onCompletion(MediaPlayer mps) {
	                     mps.release();
	                 }
	
	       });

        }

Thanks in advance,
~G