http://androiddev.orkitra.com/?p=30756
I am writing the following code,this code is for creating a class which calls a class
DataBaseAdapter
. the
Class is responsible for all database connectivity and methods are there for storing values in database.:I am getting the error,sql Exception,database already closed. but I am not getting why and how.?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},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,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,handle = 0x8ccc98,type = w,r/w = (0,0) 03-13 17:09:33.588: D/sqliteDatabaseCpp(1095): DB info: open db,file size = 4096 03-13 17:09:33.588: D/sqliteDatabaseCpp(1095): DB info: path = /data/data/com.example.devicecontrolpanel/databases,handle: 0x8f3100,handle = 0x8f3100,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,message = No such file or directory 03-13 17:16:48.164: D/sqliteDatabaseCpp(2080): DB info: path = /data/data/com.example.devicecontrolpanel/databases,handle: 0x86b220,disk free size: 777 M 03-13 17:16:48.384: D/sqliteDatabaseCpp(2080): DB info: close db,handle = 0x86b220,0) 03-13 17:16:48.384: D/sqliteDatabaseCpp(2080): DB info: open db,file size = 5120 03-13 17:16:48.384: D/sqliteDatabaseCpp(2080): DB info: path = /data/data/com.example.devicecontrolpanel/databases,handle: 0x897800,handle = 0x897800,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
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); 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,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
SQLiteOpenHelper.close()
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
object. 原文链接:https://www.f2er.com/sqlite/201029.html