This article has been dead for over three months
You
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)
<strong>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</strong>
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