Can't find the source of a DatabaseObjectNotClosedException error - android

I'm having a hard time figuring out what my problem is here. I'm receiving this error in my program, but it does not cause a crash or anything like that. I have an update I'd like to release, but I don't want to release it with this error being thrown at certain times. I've read all related posts on this error, but none apply to my situation.
I've made sure that I am closing my DatabaseHelper and SQLiteDatabase objects. I've also made sure that I'm closing all of my cursors. This error is pointing toward my method getActiveScheduleInfo, which returns a Cursor object. I've made sure that whenever I call this method, the returned cursor is closed in a Finally block.
Is this incorrect to do it this way? In my methods that call getActiveScheduleInfo, I have multiple return statements in them, based on certain conditions. So, instead of closing the cursor before each return line, I surround the condition testing with a Try, and close everything down in my Finally.
Everything looks like it should be working, so I'd really appreciate any help!
Thanks a lot!
Paul

I was able to figure this out! I hope that this helps someone else out there having the same problem.
I wasn't doing anything inherently incorrect here, but was rather taking too long to close some of my cursors. To give you a very brief background, I could not use a Managed Query or use startManagingCursor, since this code was in a custom class, not an activity. I am building against Android 2.0 (API level 5) so I am not using the new CursorLoader object.
I was taking the following steps:
Opening the database.
Creating a new Cursor and performing my query.
Iterating through the cursor and performing the needed tasks
Performing some other logic
Closing the Cursor and Database in a Finally block.
I found out that my step 4, performing some other logic, coming before closing my Cursor, was causing it to, for lack of a better term, timeout and cause this error. From now on, I read the necessary data from the Cursor, and not ONE LINE OF CODE FURTHER, I close the Cursor. :) This has completely eliminated these random errors, and I have clean-running code again.
I hope that helps others having the same problem! Take care,
Paul

Related

ClassLoader.class "source not found" error when instantiating a database class in android

I am trying to implement Content Providers and Cursor Loaders to get away from cursors as recommended by Android/Google. However, I'm having a terrible time of it. I'm using the tutorials at http://mobile.tutsplus.com/tutorials/android/android-sdk_content-providers/ as my guide and the simplest thing just isn't working. At the beginning of my Activity, I'm doing the following:
SQLData entry = new SQLData(getApplicationContext());
I've also tried
SQLData entry = new SQLData(this);
SQLData is the name of my database class. What I'd like to do after this line of code is create and populate the database using the methods from the content provider class I've created. However, when I try to move past this line in the debugger, a ClassLoader.class window opens, with the message "source not found". I've reloaded and refreshed and cleaned my package, but this doesn't help. I'm happy to provide all the code for my database and content provider classes, but I'm not sure that's what's needed here. Does anyone know how to approach this issue?
Thanks very much!
In android, or any java dev; you may find it more useful to write JUnit tests and put lots of
Log.v(TAG, "message about " + variable);
in your code instead of using the debugger...
I write Java code as my job and use the debug option maybe twice a year as a last resort...
the JUnit tests get my errors out and save me TONS of time, stepping through code in the debugger can be a very time consuming thing...
just a tip, and it may just be my personal pref...

How to over come database not opened exception?

I am implementing an app related to database.
So many times I am calling open and close database connection to insert, update and delete.
It is working fine.
But some times I am getting a database not opened exception in different situations.
How to solve these issues?
Well unless you put proper exception handling you would never know what causes this.
However a good idea is to adopt good ORM mapper for SQL Light with Android and this will improve your database interactions and exception handling and opening and closing it efficiently.
You can opt for SUGAR or ORMLight if you wish; In my opinion this should help you to fix your problem.
Based on the information you provided I can assume that the problem is in your business logic and nobody but you should be able to tell you the root cause.
Without your code here, we won't be able to point you to exact place.
One of the possible reasons can be that by your business logic you are trying to do some operation (insert, update whatever) on closed database.
You can do some workaround to try to ensure that your DB is always open when it is needed. If you implement database getter method with so called lazy initialization approach it will guarantee at least, that the DB is open when you need to access it.
Here is what I am talking about:
1. make a public method which supposed to return DB object:
public SQLiteDatabase getDB() {
if ((mDataBase == null) || (!mDataBase.isOpen())) {
// create or open your database using an OpenHelper
mDataBase = SQLiteOpenHelper.getWritableDatabase();
}
return mDataBase;
}
Now, everywhere in your code use this method to access the DB instead of directly accessing a variable mDataBase.
Note that the code is just to give you an idea and not actually compilable.
Still, I would recommend you to fix your business logic instead of using this workaround.

ListView update on insert, edit, delete notifyDataSetChanged() not working

I have a ListView bound to a SimpleCursorAdapter, and I want it to refresh when I modify the database (by inserting, updating or deleting rows). cursor.notifyDataSetChanged() has no effect (it's called on the UI thread) and ListView.removeViewAt(int) throws an UnsupportedOperationException.
What am I supposed to do on Android to get such a basic behavior?
Note that the database is correctly affected and the modification is shown when I restart the activity. But restarting the activity is not an option here, and changing the ListView adapter is the last resource here, since it's a hack and can't guarantee a smooth transition
DISCLAIMER
Quite basic question, asked millions of times and answered zero.
Please, do not answer if you have never done this in your code, don't ask for mine, and don't bother with try this or try that. Only answer if you know how it's done
From API >= 11 the way to do this is using a CursorLoader, this is also included in the Android Compatibility Library, so you can also use this if you are targeting a previous Android version. CursorLoader will make the query in a background thread and return you the cursor. You will need to implement a ContentProvider. You can read the documentation to get an idea of how to use it. Basically you init a loader and then you restart it when you know data has changed. In the callback you just swap the cursor of your adapter.
Or you can just use requery() on the Cursor. The adapter will get automatically notified of the changes. This method is deprecated now and, of course, it's not the recommended way.

Using the same database in successive activities in Android without memory leak

I'll preface this question with the note that I have looked at this similar question, but I'm still encountering issues. Basically, I want to access the same database in two activities in my Android application. However, when I open it in the second activity, I'm getting two series of messages in my LogCat:
First:
"Uncaught exception thrown by finalizer (will be discarded):
Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor#436053b8 on dogs that has not been deactivated or closed
at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)"
(dogs is the name of a table in my database, dog_data)
Second:
"ERROR/Database(1316): Leak found
ERROR/Database(1316): java.lang.IllegalStateException: /data/data/com..../databases/dog_data SQLiteDatabase created and never closed"
As far as I can tell, I am closing my database upon exiting the first activity. Following the style of the notepad tutorial, I have a wrapper class "DbAdapter" around my SQLiteDatabase, and in the onPause() method of the first activity, I call the close method on that Adapter (which calls the close methods on my SQLiteDatabase and my SQLiteOpenHelper).
I think the issue is how I am trying to reopen the database in my second activity:
SQLiteDatabase db = openOrCreateDatabase("dog_data",
SQLiteDatabase.CREATE_IF_NECESSARY, null);
(I choose not to use a wrapper because I only needed to run one query on the database, perhaps this is an issue).
Can someone advise as to where my issue might be? I'll admit (as may be clear from my question) that I don't fully understand the implications of "closing" a database (the documentation for SQLiteDatabase.close() is not particularly specific), which is probably the main reason for my problem.
Thanks.
Just in case someone happens to encounter a similar issue (seems possible but probably unlikely), I recently stumbled onto the solution. In the insert method of my "DbAdapter", I was (stupidly) checking uniqueness via a query for a row with a given value for one of the fields, and seeing whether that query returned any rows. This was creating a cursor that I wasn't closing, which resulted in the "Finalizing cursor" error noted above.
I've received that error before and had to use cursor.close() to correct the issue. I'm not exactly sure why because there are times when I didn't use close() and received no error. Maybe it's a warning that only gets noticed when it is sitting next to a show stopping error?
I will say the proper procedure is open database connection -> create cursor by running db method -> iterate through cursor -> close cursor -> close database connection.

Viewing an Android database cursor

Would anyone know how I can view what a cursor has in it during debugging so that I can determine the functionality of my database helper?
It keeps acting like it's returning data, but then when I attempt to use the cursor.isNull(0) method, I keep getting NullPointerException thrown and not being able to see what the cursor has in it while stepping through the execution is really frustrating me.
Any help would be extremely appreciated.
Thanks.
Android has provided a specific class just for debugging Cursors. It is called DatabaseUtils.
Call the method DatabaseUtils.dumpCursorToString(cursor) to view the contents of your cursor.
This helper loops through and prints out the content of the Cursor for you, and returns the cursor to its original position so that it doesn't mess up your iterating logic.
If that's null pointer exception, it seems your cursor really is null.
I would use Log.d() to help debug my cursors, you can simply create a helper method to dump the whole row of your cursor to LogCat.

Categories

Resources