cursor.moveToNext()会出异常,如下

E/AndroidRuntime( 2249): FATAL EXCEPTION: Thread-49
E/AndroidRuntime( 2249): java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:962)
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:599)
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348)
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894)
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834)
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
E/AndroidRuntime( 2249): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
E/AndroidRuntime( 2249): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
E/AndroidRuntime( 2249): at android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)

解决办法,调用cursor.getCount().

原因大概如下:

当我们第一调用android.database.sqlite.SQLiteCursor的getCount()时,当前线程会锁定数据库,在该操作完成后才解锁。

其调用关系如下:
at android.database.sqlite.SQLiteQuery.native_fill_window(Native Method) 
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:73) 
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:287) 
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:268) 
at android.widget.CursorAdapter.getCount(CursorAdapter.java:132) 

如果是第一次调用SQLiteCursor的getCount()的话,在getCount()中,它会调用fillWindow(),
在SQLiteCursor的fillWindow()中,它又会调用SQLiteQuery的fillWindow()
android.database.sqlite.SQLiteCursor的相关源码如下:
@Override
public int getCount() {
if (mCount == NO_COUNT) {
fillWindow(0);
}
return mCount;
}
private void fillWindow (int startPos) {
if (mWindow == null) {
// If there isn't a window set already it will only be accessed locally
mWindow = new CursorWindow(true /* the window is local only */);
} else {
mCursorState++;
queryThreadLock();
try {
mWindow.clear();
} finally {
queryThreadUnlock();
}
}
mWindow.setStartPosition(startPos);
mCount = mQuery.fillWindow(mWindow, mInitialRead, 0);
// return -1 means not finished
if (mCount == NO_COUNT){
mCount = startPos + mInitialRead;
Thread t = new Thread(new QueryThread(mCursorState), "query thread");
t.start();
}

在SQLiteQuery的fillWindow()中,它首先需要lock数据库,然后调用JNI层的native_fill_window()进行数据库操作,在其操作完成之后才unlock数据库。
android.database.sqlite.SQLiteQuery的相关源码如下:
/**
* Reads rows into a buffer. This method acquires the database lock.
*
* @param window The window to fill into
* @return number of total rows in the query
*/
int fillWindow(CursorWindow window,
int maxRead, int lastPos) {
long timeStart = SystemClock.uptimeMillis();
mDatabase.lock();
mDatabase.logTimeStat(mSql, timeStart, SQLiteDatabase.GET_LOCK_LOG_PREFIX);
try {
acquireReference();
try {
window.acquireReference();
// if the start pos is not equal to 0, then most likely window is
// too small for the data set, loading by another thread
// is not safe in this situation. the native code will ignore maxRead
int numRows = native_fill_window(window, window.getStartPosition(), mOffsetIndex,
maxRead, lastPos);
// Logging
if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
Log.d(TAG, "fillWindow(): " + mSql);
}
mDatabase.logTimeStat(mSql, timeStart);
return numRows;
}catch (IllegalStateException e){
// simply ignore it
return 0;
} catch (SQLiteDatabaseCorruptException e) {
mDatabase.onCorruption();
throw e;
} finally {
window.releaseReference();
}
} finally {
releaseReference();
mDatabase.unlock();
}
}

结束!

转载于:https://www.cnblogs.com/littlezan/p/3783815.html

SQLite cursor.moveToNext()相关推荐

  1. python sqlite cursor

    https://docs.python.org/3/library/sqlite3.html#cursor-objects class sqlite3.Cursor 方法 描述 execute(sql ...

  2. Android:数据库增删改查、SQLite、ORM、Cursor

    1.继承类SQLiteOpenHelper: public class MySQLiteHelper extends SQLiteOpenHelper {//重写构造方法public MySQLite ...

  3. cursor 的moveToFirst和moveToNext和moveToPrevious以及moveToLast

    查询出来的cursor的初始位置是指向第一条记录的前一个位置的,cursor.moveToFirst()指向查询结果的第一个位置.一般通过判断cursor.moveToFirst()的值为true或f ...

  4. android数据库isnull,Android中SQLite数据库知识点总结

    SQLite 数据库简介 SQLite 是一个轻量级数据库,它是D. Richard Hipp建立的公有领域项目,在2000年发布了第一个版本.它的设计目标是嵌入式的,而且占用资源非常低,在内存中只需 ...

  5. 基础学习总结(四)--SQLite

    1. SQLiteDatabase 操作SQLite数据库的类.可以执行SQL语句,对数据库进行增.删.查.改的操作.也可以进行transaction的控制.很多类对数据库的操作最终都是通过SQLit ...

  6. Android存储方式之SQLite

    前言 SQLite数据库操作在Android开发中非常常用 今天我将带大家全面了解关于SQLite数据库的操作(增.删.查.改) 目录 1. SQLite数据库介绍 SQLite是Android内置的 ...

  7. android sqlite操作(2)

    以下只是我个人的浅见,大神请忽略~ 这一篇说一下sqlite的相关操作,其实安卓提供了相当多的操作sqlite的方法,这里我介绍下我常用的方法. (1)创建一个数据库文件,这个很简单 1 File d ...

  8. 在 Android 应用程序中使用 SQLite 数据库以及怎么用

    part one : android SQLite 简单介绍 SQLite 介绍 SQLite 一个非常流行的嵌入式数据库.它支持 SQL 语言,而且仅仅利用非常少的内存就有非常好的性能.此外它还是开 ...

  9. Android数据存储(三)——SQLite

    如果需要一个更加健壮的数据存储机制,则需要使用一个关系型数据库,在Android上,则为SQLlite. SQLite的特点:轻量级.嵌入式的.关系型数据库.可移植性好,易使用,小,高效且可靠,与使用 ...

最新文章

  1. 以太坊Solidity函数的external/internal,public/private区别
  2. arch linux 同步时间,ArchLinux 设置系统时间
  3. 指标实现层级_企业如何构建核心指标系统,实现业务运营效率提升90%?
  4. 数据结构与算法--4.使用堆栈模拟队列
  5. echart 饼图图例legend支持滑动
  6. python json的中文读取与中文写入
  7. Windows10/Servers2016应用商店恢复/安装
  8. 三线压力传感器原理_电喷摩托车进气压力传感器原理与检测
  9. opencv图像分析与处理(7)- 频率域滤波的基础公式、步骤与C++实现
  10. .NET Core 如何验证信用卡卡号
  11. 中国二十五首必听的网络原创歌曲
  12. 对于教育改革的一些省思
  13. iOS GitHub上常用第三方框架
  14. java des ecb_java DES ECB模式对称加密解密
  15. 【Python】pyqt5-----QObject
  16. W25Q64Flash芯片STM32操作
  17. android studio 如何查看帮助文档
  18. matlab win32错误,尝试运行Matlab-Compiler-Runtime应用程序时Windows 7中出现SxS错误
  19. oracle采购业务流程,直发(从供应商采购直接发到客户)的业务流程
  20. Curio for Mac(头脑风暴思维导图)

热门文章

  1. android图片混淆还原,图片混淆还原1.2版本
  2. java处理pdf文件——iText的使用
  3. ORM框架之Mybatis(四)MyBatis生成器,逆向工程生成实体类和SQL
  4. [文摘20100706】软件架构师应该知道的97件事
  5. 数字高程模型和地图——thematicmapping.org译文(一)
  6. 计算机键盘prtscr,键盘上的SCR是什么意思(电脑截图的快捷方式都有哪些)
  7. linux oracle查询乱码问题,linux中oracle中文乱码解决方法
  8. hbase 查询_不用ES也能海量数据复杂查询秒回
  9. ubuntu18.04下hadoop安装与集群配置
  10. vue中使用kindeditor编辑器_vue中使用kindeditor富文本编辑器