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();
}
Related
I'm trying to do a query with in a query
id = mCursor.getInt(mCursor.getColumnIndex(DatabaseHelper.COLUMN_SUBJECT_ID));
S = new Subject(id, getSubjectDescById(id));
Subjects.add(S);
the getSubjectDescById() function opens up another cursor on its own.
mCursor is opened before the code and closed after it.
Is it risky to have nested Cursors? If so what would be a better alternative to my code
I have not tested this though but i think,Yes you can use Nested cursors
Scenario:
Step-1> Open CURSOR-1
Step-2> Open CURSOR-2 and Use that cursor as a pointer for the new Cursor you care going to create
Step-3> Close CURSOR-2
Step-4> Close Cursor-1
Try this Sample::
private void DemoFunction() throws Exception {
DatabaseHandler mHelper;
SQLiteDatabase db = null;
Cursor mCursor1 = null;
Cursor mCursor2 = null;
try {
mHelper = new DatabaseHandler(getActivity());
db = mHelper.getReadableDatabase();
//make query for buffet-type
mCursor1 = db.rawQuery("<------My First Query ------>", null);
if(mCursor1.moveToFirst()){
do{
mCursor2 = db.rawQuery("<------My Second Query ------>", null);
if(mCursor2.moveToFirst()){
do{
}while(mCursor2.moveToNext());
Log.d("", "");
}
}while(mCursor1.moveToNext());
Log.d("", "");
}
} catch (Exception e) {
if(isErr==false){
errMsg=e.getLocalizedMessage();
isErr=true;
}
throw e;
}finally{
if(db!=null){
if(db.isOpen()) db.close();
}
if(mCursor1!=null||mCursor2!=null){
if(!mCursor2.isClosed())mCursor2.close();
if(!mCursor1.isClosed())mCursor1.close();
}
}
}
Note:- Make sure you close all the cursors
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.
I am trying to access sqlite database in my app and getting this exception:
12-27 11:32:12.760: E/Exception:(746): java.lang.IllegalStateException: attempt to acquire a reference on a close SQLiteClosable Exception occured in ContactListOfNumbersForWhichRuleIsAlreadySpecified() of DatabaseHandlerRule.java
I am using this code:
public ArrayList<String> ContactListOfNumbersForWhichRuleIsAlreadySpecified(DatabaseHandlerRule Activity)
{
ContactRule contact = null;
Cursor cursor = null;
SQLiteDatabase db = null;
ArrayList<String> contactList = null;
try
{
contactList = new ArrayList<String>();
// SQLiteActivity1.ReadingAllContactsRule(SplashActivity.s_dbRule);
String selectQuery = "SELECT * FROM " + TABLE_CONTACTS + " WHERE "+KEY_NAME+" !='"
+"abcde#$%&*()##$%"+"'"+" AND "+KEY_PH_NO+"!='"+"abcde#$%&*()##$%"+"'"+" AND "+KEY_DATE+" ='"+"0"+"'";
db = this.getReadableDatabase();
if (!db.isOpen()) {
db = SQLiteDatabase.openDatabase(
"/data/data/com.velosys.smsManager/databases/rulesManager",
null, SQLiteDatabase.OPEN_READWRITE);
}
cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
contact = new ContactRule();
contact.setID(Integer.parseInt(cursor.getString(0)));
contact.setName(cursor.getString(1));
contact.setPhoneNumber(cursor.getString(2));
contact.setFolderName(cursor.getString(3));
contact.setParentFolderAddress(cursor.getString(4));
contact.setTime(cursor.getLong(5));
contact.setDate(cursor.getLong(6));
// Adding contact to list
contactList.add(contact.getName());
} while (cursor.moveToNext());
}
else if(!cursor.moveToFirst())
{
Log.e("Message: ","Rule is not specified for even a single number in database");
return contactList;
}
}
catch(Exception e)
{
Log.e("Exception: ",e+" Exception occured in ContactListOfNumbersForWhichRuleIsAlreadySpecified() of DatabaseHandlerRule.java");
}
finally
{
if(cursor != null && !cursor.isClosed())
cursor.close();
if(db != null && db.isOpen())
db.close();
}
return contactList;
}
I have searched for the reasons behind this exception but nothing implies to my case:
I am not trying to write but read the database.Hence no question arises here about concurrency.
I am using instance of Database helper class in db = this.getReadableDatabase();
I am closing database properly each and everytime i open it.
Please help me.Thanks in advance.
Edit:
Its strange.After removing finally and putting the code without finallly block,everything is working fine.Can anyone please tell me the reason behind this?
//finally
{
if(cursor != null && !cursor.isClosed())
cursor.close();
if(db != null && db.isOpen())
db.close();
}
Please remove finally block. in that you have close db and cursor so it this error comes.
In the statement db = this.getReadableDatabase();, I'm not sure of what context you are using. So declare a global context like Context context = this; then call that statement as db = context.getReadableDatabase();
Its strange.After removing finally and putting the code without finallly block,everything is working fine.Can anyone please tell me the reason behind this?
//finally
{
if(cursor != null && !cursor.isClosed())
cursor.close();
if(db != null && db.isOpen())
db.close();
}
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;
}
}
I created a static method to access my database on one of my activities but I keep getting error on opening the database.
MainActivity
public static String getStudentData() {
SQLiteDatabase sampleDB = null;
try {
//NOT WORKING
sampleDB = SQLiteDatabase.openDatabase("studentDB",null, SQLiteDatabase.CREATE_IF_NECESSARY);
//Also not working
//sampleDB = SQLiteDatabase.openOrCreateDatabase("studentDB", null);
Cursor c = sampleDB.rawQuery("SELECT * FROM student where id='1'", null);
if (c != null ) {
if (c.moveToFirst()) {
do {
//...
}while (c.moveToNext());
}
}
c.close();
} catch (Exception se ) {
} finally {
sampleDB.close();
}
}
OtherActivity
String student = MainActivity.getStudentData();
I have been getting sqlite3_open_v2("studentDB", &handle, 6, NULL) failed. Cant find what's wrong... I have also tried using MODE_WORLD_WRITEABLE. Currently using MODE_PRIVATEfor database creation. Please help me out!
First argument to openDatabase should be full path to db so if:
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/YOUR_PACKAGE/databases/";
private static String DB_NAME = "studentDB";
then you should call:
sampleDB = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
Use a method ContextWrapper#getDatabasePath(java.lang.String) and pass the result to SQLiteDatabase.openDatabase:
File dbFile= myActivity.getDatabasePath("studentDB");
sampleDB = SQLiteDatabase.openDatabase(dbFile.getAbsolutePath(), null, SQLiteDatabase.CREATE_IF_NECESSARY);