android - SQLite disk IO exception and can't open database exception -
i have gone through other similar questions did not answer.
in android app i'm opening pre-built database. in assets folder , copied using sqliteopenhelper, if not present. class:
import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.outputstream; import android.content.context; import android.database.sqlexception; import android.database.sqlite.sqlitedatabase; import android.database.sqlite.sqliteopenhelper; public class externaldbopenhelper extends sqliteopenhelper { public static string db_path; public static string db_name; public sqlitedatabase database; public final context context; public sqlitedatabase getdb() { return database; } public externaldbopenhelper(context context, string databasename) { super(context, databasename, null, 1); this.context = context; string packagename = context.getpackagename(); db_path = string.format("//data//data//%s//databases//", packagename); db_name = databasename; opendatabase(); } public void createdatabase() { boolean dbexist = checkdatabase(); if (!dbexist) { this.getreadabledatabase(); try { copydatabase(); } catch (ioexception e) { // log.e(this.getclass().tostring(), "copying error"); //throw new error("error copying database!"); } } else { // log.i(this.getclass().tostring(), "database exists"); } } private boolean checkdatabase() { sqlitedatabase checkdb = null; try { string path = db_path + db_name; checkdb = sqlitedatabase.opendatabase(path, null, sqlitedatabase.open_readonly); } catch (sqlexception e) { // log.e(this.getclass().tostring(), "error while checking db"); } if (checkdb != null) { checkdb.close(); } return checkdb != null; } private void copydatabase() throws ioexception { inputstream externaldbstream = context.getassets().open(db_name); string outfilename = db_path + db_name; outputstream localdbstream = new fileoutputstream(outfilename); byte[] buffer = new byte[1024]; int bytesread; while ((bytesread = externaldbstream.read(buffer)) > 0) { localdbstream.write(buffer, 0, bytesread); } localdbstream.close(); externaldbstream.close(); } public sqlitedatabase opendatabase() throws sqlexception { string path = db_path + db_name; if (database == null) { createdatabase(); database = sqlitedatabase.opendatabase(path, null, sqlitedatabase.open_readwrite); //caused line } return database; } @override public synchronized void close() { if (database != null) { database.close(); } super.close(); } @override public void oncreate(sqlitedatabase db) { } @override public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { } }
and in activity:
private static final string db_name = "mydb.sqlite"; private sqlitedatabase database; private externaldbopenhelper dbopenhelper; //in oncreate() dbopenhelper = new externaldbopenhelper(this,db_name); database = dbopenhelper.opendatabase();
in app repeatedly query database using cursor , rawquery. open database open_readonly never modify it. so wasn't closing before. added now:
@override protected void ondestroy() { dbopenhelper.close(); super.ondestroy(); }
was problem? had never experienced sqlite disk io exception , can't open database exception before(without dbopenhelper.close();
. reported once each in crash report). both times apps crashed on launch , caused line
database = sqlitedatabase.opendatabase(path, null, sqlitedatabase.open_readwrite);
in opendatabase() in theexternaldbopenhelper class.
i'm unable reproduce errors. 2 devices reported have device names "other" , blank.
android.database.sqlite.sqlitecantopendatabaseexception in android.database.sqlite.sqlitedatabase.dbopen: java.lang.runtimeexception: unable start activity componentinfo{com.technicosa.unjumble/com.technicosa.unjumble.mainactivity}: android.database.sqlite.sqlitecantopendatabaseexception: unable open database file @ android.app.activitythread.performlaunchactivity(activitythread.java:1956) @ android.app.activitythread.handlelaunchactivity(activitythread.java:1981) @ android.app.activitythread.access$600(activitythread.java:123) @ android.app.activitythread$h.handlemessage(activitythread.java:1147) @ android.os.handler.dispatchmessage(handler.java:99) @ android.os.looper.loop(looper.java:137) @ android.app.activitythread.main(activitythread.java:4424) @ java.lang.reflect.method.invokenative(native method) @ java.lang.reflect.method.invoke(method.java:511) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:784) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:551) @ dalvik.system.nativestart.main(native method) caused by: android.database.sqlite.sqlitecantopendatabaseexception: unable open database file @ android.database.sqlite.sqlitedatabase.dbopen(native method) @ android.database.sqlite.sqlitedatabase.opendatabase(sqlitedatabase.java:1013) @ android.database.sqlite.sqlitedatabase.opendatabase(sqlitedatabase.java:986) @ android.database.sqlite.sqlitedatabase.opendatabase(sqlitedatabase.java:1024) @ android.database.sqlite.sqlitedatabase.opendatabase(sqlitedatabase.java:986) @ android.database.sqlite.sqlitedatabase.opendatabase(sqlitedatabase.java:962) @ com.technicosa.unjumble.dbhelper.externaldbopenhelper.opendatabase(externaldbopenhelper.java:90) @ com.technicosa.unjumble.dbhelper.externaldbopenhelper.<init>(externaldbopenhelper.java:33) @ com.technicosa.unjumble.mainactivity.oncreate(mainactivity.java:131) @ android.app.activity.performcreate(activity.java:4465) @ android.app.instrumentation.callactivityoncreate(instrumentation.java:1049) @ android.app.activitythread.performlaunchactivity(activitythread.java:1920) ... 11 more
look @ this working charm
public class smartopenhelper extends sqliteopenhelper { private context context; private sqlitedatabase mydatabase; private string db_sql; private smartversionhandler smartversionhandler; smartopenhelper(context context, string dbname, int dbversion, string dbsqlname, smartversionhandler smartversionhandler) throws ioexception { super(context, dbname, null, dbversion); this.context = context; this.db_sql = dbsqlname; this.smartversionhandler = smartversionhandler; } @override public void oncreate(sqlitedatabase db) { try { bufferedinputstream instream = new bufferedinputstream(context.getassets().open(db_sql)); string sql = ""; int character = -2; { character = instream.read(); if ((character != -1) && (character != -2)) sql += (char) character; else break; } while (true); system.out.println("oncreate db sql = " + sql.split("\n")); string[] arrsql = sql.split("\n"); (int = 0; < arrsql.length; i++) { db.execsql(arrsql[i]); } } catch (ioexception e) { e.printstacktrace(); } if (this.smartversionhandler != null) { this.smartversionhandler.oninstalling(smartapplication.ref_smart_application); } } @override public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { try { bufferedinputstream instream = new bufferedinputstream(context.getassets().open(db_sql)); string sql = ""; int character = -2; { character = instream.read(); if ((character != -1) && (character != -2)) sql += (char) character; else break; } while (true); system.out.println("onupgrade db sql = " + sql.split("\n")); string[] arrsql = sql.split("\n"); (int = 0; < arrsql.length; i++) { db.execsql(arrsql[i]); } } catch (ioexception e) { e.printstacktrace(); } if (this.smartversionhandler != null) { this.smartversionhandler.onupgrading(oldversion, newversion, smartapplication.ref_smart_application); } } public sqlitedatabase getopendatabase() { return mydatabase; } public synchronized void close() { if (mydatabase != null) { mydatabase.close(); } super.close(); } }
Comments
Post a Comment