Getting exception while accessing sqlite database in android - android

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();
}

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();
}

Sqlite can i use nester cursors?

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

Error with SQLite cursor

I am trying to get all items from the table in sqlite and need to display it in List View.
Here is my code for getting Items
public List<MenuData> getMenuItem(){
SQLiteDatabase db;
Cursor cursor=null;
List<MenuData> menuList = new ArrayList<MenuData>();
db=getReadableDatabase();
String query ="SELECT * from "+TABLE_NAME_MENU;
try{
cursor = db.rawQuery (query, null );
}
catch (NullPointerException e){
Log.e("Error","Null Pointer Exception");
}
if ( cursor.moveToFirst()) {
do {
MenuData menuData= new MenuData();
menuData.setKEY_ITEM_NAME(cursor.getString(cursor.getColumnIndex(KEY_ITEM_NAME)));
menuData.setKEY_ITEM_CATEGORY(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CATEGORY)));
menuData.setKEY_ITEM_CONTENTS(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CONTENTS)));
menuData.setKEY_ITEM_TYPE(cursor.getString(cursor.getColumnIndex(KEY_ITEM_TYPE)));
menuData.setKEY_PRICE(cursor.getString(cursor.getColumnIndex(KEY_PRICE)));
menuList.add(menuData);
} while (cursor.moveToNext());
}
return menuList;
}
My problem is I got the result menuList of last row of the table and it has same number of rows in table. So the list view has all the same items.
Move the MenuData menuData= new MenuData() inside the do-while loop so you're creating new objects instead of updating the same object over and over again.
Also, change
if (cursor!=null) {
cursor.moveToFirst();
to
if (cursor.moveToFirst()) {
so your code doesn't crash in case there are no result rows. Checking for cursor != null is not really necessary.
plz correct your code with this structure
if(cursor.getCount() != 0 && cursor != null)
{
do
{
your values..
}while(cursor.moveToNext())
}
all data is store MenuData then Menudata values are attached to Listview..
Maybe you dont't close the cursor. my suggestion of code:
public List<MenuData> getMenuItem(){
List<MenuData> menuList = new ArrayList<MenuData>();
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery ("SELECT * from " + TABLE_NAME_MENU, null);
try {
if ( cursor.moveToFirst()) {
do {
MenuData menuData = new MenuData();
menuData.setKEY_ITEM_NAME(cursor.getString(cursor.getColumnIndex(KEY_ITEM_NAME)));
menuData.setKEY_ITEM_CATEGORY(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CATEGORY)));
menuData.setKEY_ITEM_CONTENTS(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CONTENTS)));
menuData.setKEY_ITEM_TYPE(cursor.getString(cursor.getColumnIndex(KEY_ITEM_TYPE)));
menuData.setKEY_PRICE(cursor.getString(cursor.getColumnIndex(KEY_PRICE)));
menuList.add(menuData);
} while (cursor.moveToNext());
}
} finally {
// close the cursor
if(cursor != null) {
cursor.close();
}
} catch(Exception e) {
// handle exception
}
return menuList;
}
you have to change your last part of code to:
if(cursor != null && cursor.getCount() > 0){
while(cursor.moveToNext(){
// your code
}
}
... and are you sure that problem in this code?
Check your datalist. May be your problem in your adapter.

database query returns null even if there is value in it

In my android app am trying to get values from database by passing one parameter to the where clause but it is always returning null...and theres no error in logcat...
i cant seem to figure out what is the issue here??
Please help!
the code where i am callimg the database function:
appmname=mDbHelper.getMname(appName);
applname=mDbHelper.getLname(appmname);
customername=appName+appmname+applname;
// app_formno=mDbHelper.getAppno(settings.getString("ap_First_Name", ""));
s=mDbHelper.fetchDetails(appName);
s=mDbHelper.getMainData(customername);
these are the functions returning database values:
public String getMname(String fname)
{
String mname = null;
try
{
String sql="select app_mname from lnt_data_table where app_fname = '"+fname+"'";
Cursor c=mDb.rawQuery(sql, null);
if (c != null) {
c.moveToFirst();
while (!c.isAfterLast()) {
mname=c.getString(0);
}
c.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
return mname;
}
public String getLname(String mname)
{
String lname = null;
try
{
String sql="select app_lname from lnt_data_table where app_mname= '"+mname+"'";
Cursor c=mDb.rawQuery(sql, null);
if (c != null) {
c.moveToLast();
while (c.isBeforeFirst() != true) {
lname=c.getString(0);
}
c.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
return lname;
}
if i give this toast message
Toast.makeText(ListViewDetails.this,appName+ appmname +applname, Toast.LENGTH_LONG).show();
it returns null when the database has values in it!
Try this format for calling the cursor and closing it
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
//your code
}
while (cursor.moveToNext());
}
cursor.close();
Hope it helps :)
I think you are moving to the end of the cursor before actually getting anything from it. Try changing c.moveToLast(); to c.moveToFirst() and then in the while loop just change while (c.isBeforeFirst()) to while(!c.isAfterLast())
You are currently moving to the end of the cursor and then checking if its at a position before the first entry...which is kinda impossible. Probably why you aren't getting anything back

Getting data from sqlite on android is really slow

I have this code:
DatabaseHandler db = new DatabaseHandler(this);
System.out.println("Start - " + System.currentTimeMillis());
for (int i = 1; i < db.getChampsCount() + 1; i++) {
String name = db.getChampInfo(i, "name");
String title = db.getChampInfo(i, "title");
String thumb = db.getChampInfo(i, "thumb");
System.out.println("End - " + System.currentTimeMillis());
[...]
}
and this
String getChampInfo(int id, String col) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT " + col + " FROM champions WHERE id = " + id, new String[] {});
if (cursor != null)
cursor.moveToFirst();
db.close();
return cursor.getString(0);
}
Which is a part of DatabaseHelper class
And it works ok, but the problem is it takes way too long to execute (2089ms on my android phone). Those strings are a part of the UI so I don't think I can put that in another thread. What can i do to make this code run faster?
Edit: there are exactly 110 rows
Instead of individual statement, should you not use Single sql statement ?
Just create one ArrayList which will store all the required value in the Activity class.
e.g: ArrayList<String> myData;
Now in database helper class make one function like below:
// TO get All Data of datanase which you want
public ArrayList<String> getAllData() {
ArrayList<String> subTitleList = null;
Cursor cursor = null;
try {
String queryString = "SELECT * FROM champions";
cursor = db.rawQuery(queryString, null);
if (cursor != null && cursor.moveToFirst()) {
subTitleList = new ArrayList<String>();
do {
String nextUser = new String(cursor.getString(cursor.getColumnIndex("name")));
String nextUser = new String(cursor.getString(cursor.getColumnIndex("title")));
String nextUser = new String(cursor.getString(cursor.getColumnIndex("thumb")));
subTitleList.add(nextUser);
}
while (cursor.moveToNext());
System.out.println("it comes in SubTitleList");
}
}
catch (Exception e) {
e.printStackTrace();
subTitleList = null;
}
finally {
if (cursor != null && !cursor.isClosed()) {
cursor.deactivate();
cursor.close();
cursor = null;
}
if(db != null){
db.close();
}
}
//System.out.println("SubTitleList is: "+subTitleList);
return subTitleList;
}
And now in your activity class you can call this function and get all the required data from the myData ArrayList.
myData = db.getAllData(); // i think there is no need of any ID if you are fetching all the data.
Hope you got my point.
You can definitely run those in an AsyncTask. All you have to do is pass the data into the task's parameters or if you cant figure that out just make your task have a constructor that takes the parameters and call it like this:
MyAsync ma = new MyAsync(stuff, stuff, stuff);
ma.execute();
In the task's onPostExecute() is where you can grab the data from your queries that ran in the background and then you can update the UI.
Also the other guys are kind of right. If you can combine your queries that would be best but with a table like that its not really going to give you much of a performance boost, at least I don't think.

Categories

Resources