2 iamkila iamkila 于 2013.04.16 11:26 提问

getReadableDatabase()不能在ui线程进行?

以前我一贯的写法是getReadableDatabase()和getWritableDatabase() 都是在ui线程进行的,而且在android4.0以上版本都没有任何问题,最近换了个android2.2的设备测试,发现就报错了,异常是SQLiteException 并提示database is locked这些信息,检查我对数据库的操作只不过是写完数据后读数据,应该不存在数据库被锁的问题。

思前想后,在SQLiteOpenHelper 源代码中发现到getReadableDatabase()的如何注解
/*
* Create and/or open a database. This will be the same object returned by
* {@link #getWritableDatabase} unless some problem, such as a full disk,
* requires the database to be opened read-only. In that case, a read-only
* database object will be returned. If the problem is fixed, a future call
* to {@link #getWritableDatabase} may succeed, in which case the read-only
* database object will be closed and the read/write object will be returned
* in the future.

** <p class="caution">Like {@link #getWritableDatabase}, this method may
 * take a long time to return, so you should not call it from the
 * application main thread, including from
 * {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.*

 * @throws SQLiteException if the database cannot be opened
 * @return a database object valid until {@link #getWritableDatabase}
 *     or {@link #close} is called.
 */

留意高亮部分,注解说不要写在应用的主线程,包括contentprovider的oncreate方法,我好奇的是 网上大家都是直接写在ui线程,而且看上去是可行的 为什么官方的api注解却提示不可以。还有一个奇怪的问题,就是我说过的遇到的那个异常并不是必定的,是偶尔出现的
so 说下你们的见解吧

3个回答

boliu123
boliu123   2013.04.16 16:50
已采纳

那就应该是锁了! 虽然文档是提示你应该在子线程中做,但是主线程做也不会影响的! 应该是有别的线程在异步操作这个数据库,如果别的线程中关闭了数据库,而你这里却在对数据库操作,也会出现这个bug

qiushibaiyi
qiushibaiyi   2013.04.16 11:33

android的设计就是,不让任何耗时的操作阻塞UI线程……
所有操作DB和网络请求的操作,尽量另起线程。
在以前的版本中,貌似要求不是那么严格。但是现在android对这个要求很严格…………

我的理解,本身android的效率已经被IOS甩在后面了,所以我们做开发的就不要在给android找不愉快了。把耗时操另起线程,是一个良好的习惯……

iamkila
iamkila 我其实本来就对数据库操作都包在新起的线程里面,现在找到了缓冲的解决方法了 就是在数据库不能写的时候,依然提供个可读的数据库try { db = dbHelper.getWritableDatabase(); } catch (SQLiteException ex) { db = dbHelper.getReadableDatabase(); }
接近 5 年之前 回复
ndzj981479673
ndzj981479673   2014.08.18 16:36

打开StrictMode后,创建数据库的操作都会报StrictModeReadViolation,因此要新起一个线程来完成这个操作

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!