1. 程式人生 > >SQLite Exception, Database Already Closed

SQLite Exception, Database Already Closed

I am writing the following code, this code is for creating a class which calls a class

DataBaseAdapter

. the

DataBaseAdapter

Class is responsible for all database connectivity and methods are there for storing values in database.:

public class Main extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DataBaseAdapter db = new DataBaseAdapter(getApplicationContext()); Alarm al = new Alarm(1,"qwer",new int[] {1,1,1,0,1,0,1}, 1, 382562495,"App", 1); db.addAlarm(al); ScrollView sc= (ScrollView) findViewById(R.id.scrollBody); TableLayout tb = db.getAllAlarmList(getApplicationContext()); sc.addView(tb); } }

This is my logcat:

03-13 17:09:33.388: D/SqliteDatabaseCpp(1095): Registering sqlite logging func: /data/data/com.example.devicecontrolpanel/databases/AlarmSystem 03-13 17:09:33.408: D/SqliteDatabaseCpp(1095): DB info: open db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, flag = 6, cannot stat file, errno = 2, message = No such file or directory 03-13 17:09:33.408: D/SqliteDatabaseCpp(1095): DB info: path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle: 0x8ccc98, type: w, r/w: (0,1), mode: truncate, disk free size: 777 M 03-13 17:09:33.588: D/SqliteDatabaseCpp(1095): DB info: close db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle = 0x8ccc98, type = w, r/w = (0, 0) 03-13 17:09:33.588: D/SqliteDatabaseCpp(1095): DB info: open db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, flag = 6, file size = 4096 03-13 17:09:33.588: D/SqliteDatabaseCpp(1095): DB info: path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle: 0x8f3100, type: w, r/w: (0,1), mode: truncate, disk free size: 777 M 03-13 17:09:33.588: D/SqliteDatabaseCpp(1095): DB info: close db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle = 0x8f3100, type = w, r/w = (0, 0) 03-13 17:09:33.598: D/AndroidRuntime(1095): Shutting down VM 03-13 17:09:33.598: W/dalvikvm(1095): threadid=1: thread exiting with uncaught exception (group=0x40ae0228) 03-13 17:09:33.618: E/AndroidRuntime(1095): FATAL EXCEPTION: main 03-13 17:09:33.618: E/AndroidRuntime(1095): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.devicecontrolpanel/com.example.devicecontrolpanel.Main}: java.lang.IllegalStateException: database /data/data/com.example.devicecontrolpanel/databases/AlarmSystem (conn# 0) already closed 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2205) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2240) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.ActivityThread.access$600(ActivityThread.java:139) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.os.Handler.dispatchMessage(Handler.java:99) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.os.Looper.loop(Looper.java:156) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.ActivityThread.main(ActivityThread.java:4987) 03-13 17:09:33.618: E/AndroidRuntime(1095): at java.lang.reflect.Method.invokeNative(Native Method) 03-13 17:09:33.618: E/AndroidRuntime(1095): at java.lang.reflect.Method.invoke(Method.java:511) 03-13 17:09:33.618: E/AndroidRuntime(1095): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 03-13 17:09:33.618: E/AndroidRuntime(1095): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 03-13 17:09:33.618: E/AndroidRuntime(1095): at dalvik.system.NativeStart.main(Native Method) 03-13 17:09:33.618: E/AndroidRuntime(1095): Caused by: java.lang.IllegalStateException: database /data/data/com.example.devicecontrolpanel/databases/AlarmSystem (conn# 0) already closed 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2194) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:448) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:435) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:79) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:176) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:168) 03-13 17:09:33.618: E/AndroidRuntime(1095): at com.example.devicecontrolpanel.DataBaseAdapter.getAlarmsCount(DataBaseAdapter.java:190) 03-13 17:09:33.618: E/AndroidRuntime(1095): at com.example.devicecontrolpanel.DataBaseAdapter.getAllAlarmList(DataBaseAdapter.java:117) 03-13 17:09:33.618: E/AndroidRuntime(1095): at com.example.devicecontrolpanel.Main.onCreate(Main.java:19) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.Activity.performCreate(Activity.java:4538) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071) 03-13 17:09:33.618: E/AndroidRuntime(1095): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2161) 03-13 17:09:33.618: E/AndroidRuntime(1095): ... 11 more 03-13 17:16:48.144: D/SqliteDatabaseCpp(2080): Registering sqlite logging func: /data/data/com.example.devicecontrolpanel/databases/AlarmSystem 03-13 17:16:48.144: D/SqliteDatabaseCpp(2080): DB info: open db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, flag = 6, cannot stat file, errno = 2, message = No such file or directory 03-13 17:16:48.164: D/SqliteDatabaseCpp(2080): DB info: path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle: 0x86b220, type: w, r/w: (0,1), mode: truncate, disk free size: 777 M 03-13 17:16:48.384: D/SqliteDatabaseCpp(2080): DB info: close db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle = 0x86b220, type = w, r/w = (0, 0) 03-13 17:16:48.384: D/SqliteDatabaseCpp(2080): DB info: open db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, flag = 6, file size = 5120 03-13 17:16:48.384: D/SqliteDatabaseCpp(2080): DB info: path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle: 0x897800, type: w, r/w: (0,1), mode: truncate, disk free size: 777 M 03-13 17:16:48.384: D/SqliteDatabaseCpp(2080): DB info: close db, path = /data/data/com.example.devicecontrolpanel/databases , key = 9lYvmWqw, handle = 0x897800, type = w, r/w = (0, 0) 03-13 17:16:48.394: D/AndroidRuntime(2080): Shutting down VM 03-13 17:16:48.414: W/dalvikvm(2080): threadid=1: thread exiting with uncaught exception (group=0x40ae0228) 03-13 17:16:48.424: E/AndroidRuntime(2080): FATAL EXCEPTION: main 03-13 17:16:48.424: E/AndroidRuntime(2080): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.devicecontrolpanel/com.example.devicecontrolpanel.Main}: java.lang.IllegalStateException: database /data/data/com.example.devicecontrolpanel/databases/AlarmSystem (conn# 0) already closed 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2205) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2240) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.ActivityThread.access$600(ActivityThread.java:139) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.os.Handler.dispatchMessage(Handler.java:99) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.os.Looper.loop(Looper.java:156) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.ActivityThread.main(ActivityThread.java:4987) 03-13 17:16:48.424: E/AndroidRuntime(2080): at java.lang.reflect.Method.invokeNative(Native Method) 03-13 17:16:48.424: E/AndroidRuntime(2080): at java.lang.reflect.Method.invoke(Method.java:511) 03-13 17:16:48.424: E/AndroidRuntime(2080): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 03-13 17:16:48.424: E/AndroidRuntime(2080): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 03-13 17:16:48.424: E/AndroidRuntime(2080): at dalvik.system.NativeStart.main(Native Method) 03-13 17:16:48.424: E/AndroidRuntime(2080): Caused by: java.lang.IllegalStateException: database /data/data/com.example.devicecontrolpanel/databases/AlarmSystem (conn# 0) already closed 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2194) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:448) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:435) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:79) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:176) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:168) 03-13 17:16:48.424: E/AndroidRuntime(2080): at com.example.devicecontrolpanel.DataBaseAdapter.getAlarmsCount(DataBaseAdapter.java:196) 03-13 17:16:48.424: E/AndroidRuntime(2080): at com.example.devicecontrolpanel.DataBaseAdapter.getAllAlarmList(DataBaseAdapter.java:123) 03-13 17:16:48.424: E/AndroidRuntime(2080): at com.example.devicecontrolpanel.Main.onCreate(Main.java:19) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.Activity.performCreate(Activity.java:4538) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071) 03-13 17:16:48.424: E/AndroidRuntime(2080): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2161) 03-13 17:16:48.424: E/AndroidRuntime(2080): ... 11 more

I am getting the error, SQL Exception, database already closed. but I am not getting why and how.?
What to do. Please Help.

Here is the code for getAllAlarmList:

public Alarm getAlarm(int id) { SQLiteDatabase db = this.getReadableDatabase(); String[] colum = {KEY_ALARM_ID, KEY_DESC, KEY_REPEAT_DAY, KEY_REPEAT_TYPE, KEY_CALENDAR, KEY_APP, KEY_ACTIVE}; Cursor cursor = db.query(TABLE_NAME, colum, KEY_ALARM_ID +"=?", new String[] { String.valueOf(id) }, null, null, null); if (cursor != null) cursor.moveToFirst(); else return null; int alarm_id=Integer.parseInt(cursor.getString(0)); String desc = cursor.getString(1); String dayRepeat = cursor.getString(2); int[] repeatDay = new int[7]; for(int m=0;m<7;m++) { repeatDay[m]=Integer.parseInt(Character.toString(dayRepeat.charAt(m))); } int repeatType = Integer.parseInt(cursor.getString(3)); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(Long.parseLong(cursor.getString(4))); String app = cursor.getString(5); int active = Integer.parseInt(cursor.getString(6)); //change dayRepeat String to int[] Alarm alarm = new Alarm(alarm_id, desc, repeatDay, repeatType, cal.getTimeInMillis(), app, active); db.close(); return alarm; } public TableLayout getAllAlarmList(Context con) { SQLiteDatabase db = this.getReadableDatabase(); TableLayout body = new TableLayout(con); TableLayout.LayoutParams TbodyLayout = new TableLayout.LayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT)); body.setLayoutParams(TbodyLayout); body.setBackgroundColor(Color.BLACK); LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); if(getAlarmsCount()>0) { int maxCount = getAlarmsCount(); String selectQuery = "SELECT * FROM " + TABLE_NAME; Cursor cursor = db.rawQuery(selectQuery, null); if(cursor.moveToFirst()) { TableRow[] tr = new TableRow[maxCount]; CheckBox[] check = new CheckBox[maxCount]; initializeCheckBoxId(maxCount); int checkboxid = 100; int alarm_id; for(int i=0;i<maxCount;i++) { tr[i] = new TableRow(con); check[i]= new CheckBox(con); alarm_id=Integer.parseInt(cursor.getString(0)); Alarm alarm = getAlarm(alarm_id); check[i].setText(alarm.getTimeInString()+"n"+alarm.getDesc()+"n"+alarm.getRepeatTypeInString()); check[i].setVisibility(1); check[i].setEnabled(false); if(alarm.getActive()==1) { check[i].setEnabled(true); } setCheckBoxId(checkboxid+alarm.getAlarmId()); check[i].setId(checkboxid+alarm.getAlarmId()); check[i].setTextColor(Color.WHITE); tr[i].addView(check[i]); tr[i].setLayoutParams(layout); if(i%2==0) { tr[i].setBackgroundColor(Color.DKGRAY); } else { tr[i].setBackgroundColor(Color.GRAY); } body.addView(tr[i]); } } else { TextView TV = new TextView(con); TV.setText("No Alarms Set."); TV.setTextColor(Color.WHITE); TV.setVisibility(1); TableRow tableRow = new TableRow(con); tableRow.setLayoutParams(layout); body.addView(tableRow); } } else { TextView TV = new TextView(con); TV.setText("No Alarms Set."); TV.setTextColor(Color.WHITE); TV.setVisibility(1); TableRow tableRow = new TableRow(con); tableRow.setLayoutParams(layout); body.addView(tableRow); } db.close(); return body; }

Here is the code to add the alarm to the database:

public void addAlarm(Alarm alarm) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); //values.put(KEY_ALARM_ID, alarm.getAlarmId()); values.put(KEY_DESC, alarm.getDesc()); values.put(KEY_REPEAT_DAY, alarm.getRepeatDay()); values.put(KEY_REPEAT_TYPE, alarm.getRepeatType()); values.put(KEY_CALENDAR, Long.toString(alarm.getCalendarInMillis())); values.put(KEY_APP, alarm.getApp()); values.put(KEY_ACTIVE, alarm.getActive()); db.insert(TABLE_NAME, null, values); db.close(); }

here is the code for getting the alarm count:

public int getAlarmsCount() { String countQuery = "SELECT * FROM " + TABLE_NAME; SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.rawQuery(countQuery, null); cursor.close(); // return count db.close(); return cursor.getCount(); }

Answer

You call

close()

on the underlying

SQLiteDatabase

. You should call 

instead. Change all

db.close()

into

this.close()

or plain

close()
SQLiteDatabase db = this.getReadableDatabase(); ... this.close();

If you call

SQLiteDatabase.close()

instead of

SQLiteOpenHelper.close()

, the

SQLiteOpenHelper

cannot know this and returns the already closed

SQLiteDatabase

object.