100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android SQLite数据库异常: unable to open database file

Android SQLite数据库异常: unable to open database file

时间:2022-02-21 16:05:49

相关推荐

Android SQLite数据库异常: unable to open database file

Android进行数据库操作时,可能会遇到如下异常:

E AndroidRuntime: android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)E AndroidRuntime: at android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)E AndroidRuntime: at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:553)E AndroidRuntime: at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)E AndroidRuntime: at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)E AndroidRuntime: at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)E AndroidRuntime: at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)

由于SQLite底层的代码并不是很好分析,一直以来这个问题的具体原因很难定位。

从我目前接触到的信息来看,关于这个问题的原因,江湖传言有这么三个:

1、内存耗尽(几乎是最显而易见的原因);

2、进程的文件句柄Fd耗尽;

3、SQLite的临时文件不可用(自己没证实过)。

对于内存耗尽的原因比较好定位。

当大家怀疑是内存问题导致SQLite异常时,只需要在crash等日志中搜索memory关键即可:

W art : Throwing OutOfMemoryError "Could not allocate JNI Env"

如果是内存原因,那么应该可以看到类似上述的日志。

这个时候就要考虑系统当时是真的运行了过多的进程,还是存在内存泄露的问题。

对于文件句柄耗尽的原因,可以搜索类似如下的log:

E art : ashmem_create_region failed for 'indirect ref table': Too many open files

SQLite最终会调用ashmem_create_region()来分配共享内存。

如果出现上述log,那么应该就是开启了过多的文件,导致Fd耗尽。

比较常见的原因就是:Cursor开启后没有关闭。

此外,还有一些其它的场景,例如:

进程一直存在,然后不断地新建并运行HandlerThread。

如果HandlerThread在功能执行结束后不主动quit的话,

进程中就会积累出越来越多的HandlerThread。

由于HandlerThread对应的Looper也会持有Fd,

最终也会导致Fd耗尽,出现前文提到的异常。

如果怀疑是这种问题,可以使用root的手机测试你的APK。

利用ps或ps -A得到APK进程对应的pid,然后执行下述命令:

ls -al /proc/pid/fd

执行结果类似于:

图中的数字就是fd编号。

如果随着APK运行(测试),Fd不断变大(正常情况下,释放后会复用),那么就可以确定Fd存在泄露。

对于第三种情况,没仔细研究过,看过很多人写,内容几乎一样。

附上链接以备万一:/p/6ad0491404da

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。