Cannot close the Db correctly - android

Following is my code,
public class CommentsDataSource {
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_COMMENT };
public CommentsDataSource(Context context) {
dbHelper = new MySQLiteHelper(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
if (database != null) {
database.close();
}
dbHelper.close();
}
public String getComment_1() {
List<Comment> comments = new ArrayList<Comment>();
Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS,
allColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Comment comment = cursorToComment(cursor);
comments.add(comment);
cursor.moveToNext();
}
// make sure to close the cursor
cursor.close();
return comments.get(0).getComment();
}
private Comment cursorToComment(Cursor cursor) {
Comment comment = new Comment();
comment.setId(cursor.getLong(0));
comment.setComment(cursor.getString(1));
return comment;
}
public class MyService extends BackgroundService implements LocationListener {
#Override
public void onCreate() {
context = getApplicationContext();
datasource = new CommentsDataSource(context);
gps = new GPSTracker(context);
datasource.open();
mHelloTo = datasource.getComment_1();
datasource.close();
}
}
In the Above Code use to retrieve some data from database inside a Background Service. It Works Fine but Sometimes it gives the Following Error even though i close the cursor database and dbhelper correctly.
01-08 14:31:58.691: E/SQLiteDatabase(13854): close() was never explicitly called on database '/data/data/org.apache.cordova.example/databases/commments.db'

This only happens on platforms before JellyBean. JellyBean and later have this error message removed.
Even though it is logged with error log level and contains exception stacktrace, it is not an exception that was thrown. SQLiteDatabase constructor just stores the stacktrace of its caller in a member variable exception and in finalizer logs the stacktrace in case the database is still open.
You can see the stacktrace to see where the unclosed database was opened.
To get specific help with your code, include relevant parts of MySQLiteHelper in the question

Try changing this:
public String getComment_1() {
open(); // open database
List<Comment> comments = new ArrayList<Comment>();
Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS,
allColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Comment comment = cursorToComment(cursor);
comments.add(comment);
cursor.moveToNext();
}
// make sure to close the cursor
cursor.close();
close(); // close database
return comments.get(0).getComment();
}
Also what dbHelper.close(); does? You're closing the connection with the db calling database.close() so why do you need this?

You're calling the methods correctly, but please change the open() and close() methods to the following :
public void open() throws SQLException {
dbHelper= new MySQLiteHelper (ctx);
database = dbHelper.getWritableDatabase();
return this;
}
public void close() {
dbHelper.close();
}
But instead of opening and closing the database each time you make a read/write operation, I'd recommend you open() the database once in your Application.onCreate(). The closing will be done automatically when your application exits or is closed by Android OS. Since SQLite data integrity, you don't have to worry about losing data.

Related

Android: runtime exception database already closed

I'm using SQLite database for getting record of table where if specific record is exist.Always getting error while run the application = Caused by: java.lang.IllegalStateException: database /data/data/com.example.tazeen.xxx/databases/xx(conn# 0) already closed
dbhelper = new MyDbHelper(this);
SQLiteDatabase db1 = dbhelper.getReadableDatabase();
Cursor cursor = db1.rawQuery("select * from ActivityObjectList", null);
if (cursor.moveToFirst()) {
do {
imageName = cursor.getString(cursor.getColumnIndex("imageaudioPath"));
String strDownLoadStatus = cursor.getString(cursor.getColumnIndex("DownLoad_Status"));
} while (cursor.moveToNext());
}
cursor.close();
db1.close();
}
I believe you should close some thing like dbhelper.close()... instead of db1.close();
It's guess by understanding your code snippet.
You should close your sqlite db object in db helper class
#Override
public synchronized void close() {
if (mDb != null)
mDb.close();
super.close();
}
You should close sqlite database after read the table.
you would use
like this
Try{
enter code here
what do to
}
finally{
db.close();
}

Null Pointer Exception while fetching cursor object

I am getting null pointer exception while fetching the data from the SQLite table.
I am getting the null pointer exception when fetching the data using cursor like below Cursor c= db.fetchAllData();
Please have a look at the below precise code, and suggest me some ideas...
display_transaction.class
public class display_transaction extends Activity {
DisplayTestDBHelper db;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_listview);
displayListView();
}
public void displayListView() {
Cursor c= db.fetchAllData();
String[] columns={db.KEY_ID,db.KEY_DESCRIPTION,db.KEY_AMOUNT};
int[] id=new int[]{R.id.textView1,R.id.textView2};
SimpleCursorAdapter s=new SimpleCursorAdapter(this,R.layout.listviewlayout,c,columns,id,0);
ListView l=(ListView) findViewById(R.id.listview1);
l.setAdapter(s);
}
}
DisplayTestDBHelper.class
public Cursor fetchAllData() {
String TABLE_NAME="transaction_table";
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCursor = db.query(TABLE_NAME, new String[] {KEY_ID, KEY_DESCRIPTION, KEY_AMOUNT}, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
Please help me to resolve the above issue...
Thanks in advance!!!!
You didn't initialize db.
Depending on how you've implemented the helper's constructor, use something like
db = new DisplayTestDBHelper(this);
to init it, passing the activity this for a Context.
You haven't initialized db.
You need to do something like:
db = new DisplayTestDBHelper(this);

how to avoid "close() was never explicitly called on database in SQLiteDatabase" [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android error - close() was never explicitly called on database
I have a problem in my android app.
I have a singleton implemented which has a method with the following code:
public Cursor getFooCursor(Context context)
{
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");
return c;
}
when i use this, i sometimes get the error: SQLiteDatabase: close() was never explicitly called on database
how to avoid this? the problem is, i can not simply make a db.close() befor i return c, because then its empty.
The approach I use is to pass an instance of the db to a class that returns the cursor:
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();
public Cursor getFooCursor(Context context, SQLiteDatabase db ) {
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null,
null, "Test DESC");
return c;
}
db.close();
Clients should open the database, then use this method to fetch the cursor, then close both the cursor and the database when they are finished. I would recommend not using a singleton here. Instead do something like this:
public class FooDB
{
private SQLiteDatabase db = null;
private void open() throws SQLiteException
{
if (db != null)
{
throw new SQLiteException("Database already opened");
}
// Create our open helper
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
try
{
// Try to actually get the database objects
db = m_openHelper.getWritableDatabase();
}
catch (Exception e)
{
e.printStackTrace();
}
if (db == null)
{
throw new SQLiteException("Failed to open database");
}
}
private void close() throws SQLiteException
{
if (db != null)
{
db.close();
db = null;
}
}
public Cursor getFooCursor(Context context)
{
if(db == null)
throw new SQLiteException("Database not open");
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");
return c;
}
}

Why does the cursor not close in android?

I have been trying every single thing but still some how have not been able to find a solution for this. In spite of using the close method the cursor still doesn't seem to be closing. This has been frustrating me. Any help will be much appreciated. Here is my code
public class Order extends Activity{
DatabaseHelper helper;
Cursor c;
SQLiteDatabase db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.order);
String columns[] = {"_id", "Name", "Price"};
helper = new DatabaseHelper(this);
db=helper.getWritableDatabase();
c=db.query("lite", columns, null, null, null, null, null);
c.moveToFirst();
curs();
c.close();
helper.close();
}
public void curs()
{
String r = "";
while(!c.isAfterLast())
{
r=r + c.getString(c.getColumnIndex("_id")) + " "+c.getString(c.getColumnIndex("Name"))+" "+c.getString(c.getColumnIndex("Price"));
c.moveToNext();
}
}
Modify
curs();
c.close();
helper.close();
to
curs();
if(!isClosed()){
c.close();
}
helper.close();
db.close();
You have not closed your database also, try this
db.close();
c.close();
helper.close();
Also, I suggest you can declare 'Cursor' as local variable instead of global and pass it as in argument to your method 'curs'

Addressing "Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor"

I have two DB clsses, one copies the db file from assets to the phone.
the Second is where I have been putting my DB calls but in the log I am getting an awrful lot error about I should close the cursor. This I am getting confused about as all my calls have a cursor.close() on the end.
Code of second:
public class DatabaseTools extends Common {
private Context context;
private SQLiteDatabase db;
private DatabaseHelper dbHelper;
private Cursor cursor;
public DatabaseTools(Context context) {
this.context = context;
dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
}
// MARKS
public ArrayList<String> getNames(String value) {
Names = new ArrayList<String>();
selectStatement = new String[] { DB_COMMON_COL_NAME };
fromStatement = DB_COMMON_COL_VALUE + " = '" + value + "'";
cursor = db.query(
DB_DISTANCE_TABLE_NAME,
selectStatement,
fromStatement,
null,
null,
null,
null);
int distanceIndex = cursor.getColumnIndex(DB_COMMON_COL_NAME);
if (cursor.moveToFirst()) {
do {
distanceNames.add(cursor.getString(distanceIndex));
} while (cursor.moveToNext());
}
cursor.close();
return names;
}
Try the following modification to ensure you close your cursor. Also you're getting database instance in your constructor. That's not good. You should get database instance right before you work with the database, and call close() on the database, as soon as you're finished. I would suggest moving db = dbHelper.getWritableDatabase() inside the getNames(String value) method, than calling db.close() when you're done - also in finally block.
public ArrayList<String> getNames(String value) {
Names = new ArrayList<String>();
selectStatement = new String[] { DB_COMMON_COL_NAME };
fromStatement = DB_COMMON_COL_VALUE + " = '" + value + "'";
cursor = db.query(
DB_DISTANCE_TABLE_NAME,
selectStatement,
fromStatement,
null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
try {
int distanceIndex = cursor.getColumnIndexOrThrow(DB_COMMON_COL_NAME);
while(cursor.moveToNext()) {
distanceNames.add(cursor.getString(distanceIndex));
}
} finally {
if (!cursor.isClosed()) {
cursor.close();
}
}
return names;
}

Categories

Resources