android开发数据库Cursor 错误android.database.CursorWindowAllocationException

做android 开发的经常会遇android.database.CursorWindowAllocationException这样子的错误;一般出现这样的错误,大部分原因是因为没有关闭cursor,或者是因为Cursor使用不当,之前我的遇到这样的代码:

 ForecastData situation = null;
    ................
    Cursor cursor = mContext.getContentResolver().query(WEATHER_URI, null,
    null, null, null);

    try {
        if (cursor != null && cursor.moveToFirst()) {
        ...........
        cursor.close();
        }
   } catch (Exception e) {
        e.printStackTrace();
   } finally {
        if (cursor != null) {
        cursor.close();
   }
}
return situation;

}

初看一下没有什么问题,但如果Cursor cursor = mContext.getContentResolver().query这里返回的错误还是会有可能造成程序的未关闭Cursor,因此我们改成标准写法:

Cursor cursor = null;
try {
	cursor = getContentResolver().query(URI, .....);// 1
        //dosomething
} finally {
	if (cursor != null) {
		cursor.close();// 2
	}
}

这样改了之后,运行了很多个版本都一直没有问题。直到有一天一个同事发现可能查询数据库比较耗时。因此把方法放到线程里面去执行,而已每次查询的时候都会创建一个线程。没有想到上面代码又出错误了,如果您稍不留意不会怀疑这块代码的问题,因为try-finally写法不存在逻辑上的问题。由于这里未考虑到多线程场景,try-finally并不能保证query打开游标在dosomething时,被其他线程再次调用query打开游标。所以当遇到存在多线程的调用时必须对游标打开到关闭时间段添加锁,即这里是对try-finally块加锁。

下面简单解释一下:

假设:线程A执行到1处创建了一个Cursor,然后dosomething比较耗时........

线程B又来查询数据库,因此到1处又创建一个Cursor,此时如果AB执行完,就会关闭锁,看起来没有问题,但由于是同一个对象,所以AB关闭的cursor都是B创建的,因此

A创建的Cursor就没有关闭!

时间: 2024-10-15 06:42:31

android开发数据库Cursor 错误android.database.CursorWindowAllocationException的相关文章

android开发常见编程错误总结

1.设置TextView的文本颜色 1 2 3 TextView tv; ... tv.setTextColor(R.color.white); 其实这样设置的颜色是 R.color.white的资源ID值所代表的颜色值,而不是资源color下的white颜色值:正确的做法如下: 1 tv.setTextColor(getResources().getColor(R.color.white)); 这个出错的概率满高的,就是因为二者都是int类,导致编译器不报错. 2.读取Cursor中的值 1

Android开发导入常见错误

Android开发导入常见错误 1.SDK版本不对应,你可以打开你项目中的project.properties文件,修改target=android-18(我这是18) ,将18改为14(其他都可以),再改回18会重新加载,最好clean一下项目. 有时候没有R文件,那是因为你的xml文件错误了,例如:多了一个逗号之类的 2.V4包不对应,重新导入你当前环境的V4包 3.如引用了项目类型的Lib,右键项目——>properties——>android——>查看项目是否引入,查看是否勾选I

【Android开发】完美解决Android完全退出程序

背景:假说有两个Activity, Activity1和Activity2, 1跳转到2,如果要在2退出程序,一般网上比较常见的说法是用 System.exit(0) 或是 android.os.Process.killProcess(android.os.Process.myPid()) 但实际应用中,并不是能够真正退出,问题出在?1跳转到2时,如果Activity1你finish掉了,两么是可以退出程序的,但有时1跳转到2时,我们不能将Activity1 finish掉,那么在Activit

Android开发工具全面转向Android Studio(3)——AS project/module的目录结构(与Eclipse对比)

如果AS完全还没摸懂的,建议先看下Android开发工具全面转向Android Studio(2)——AS project/module的CRUD. 1.其实AS project/module的目录结构很简单,我浓缩成2张图给总结了,先看图,再看下面的文字,因为还有些细节图上体现不出来(我这个图上的项目来源于我之前的Eclipse项目,并且有lib项目库相互依赖) 2.上面的图很直观,但也很眼花缭乱,我再针对图总结下重点和疑问点. ①在AS的世界里,文件夹都以模块(module)为单位组织的,其

配置cordova的android开发环境(无android studio)

原文:配置cordova的android开发环境(无android studio) 趁元旦放假想试一下cordova,不想安装庞大的android studio,所以想最小化安装,居然花了一整天的时间才能正常编译cordova工程,记录一下过程,备将来参考. 安装环境:操作系统:windows 10 x64 第一步:安装nodejs,下载最新版本v10.15.0 第二步:设置npm安装源 npm config set registry http://registry.npm.taobao.org

Android - 插入数据库(SQLite)错误

插入数据库(SQLite)错误 本文地址: http://blog.csdn.net/caroline_wendy Error: android.database.sqlite.SQLiteException: no such table: step (code 1): ,  while compiling: INSERT INTO step(duration,date,counter) VALUES (?,?,?). 错误:插入数据库错误,没有找到表,插入表的地方写入参数,而参数地方传入空值.

Android开发- 数据库和Content Provider

SQLiteOpenHelper SQLiteOpenHelper是一个抽象类,用来实现创建.打开和升级数据库的最佳实践模式. private static class HoardDBOpenHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "myDatabase.db"; private static final String DATABASE_TABLE = "Gol

Android - SQLite游标(Cursor)错误

SQLite游标(Cursor)错误 本文地址: http://blog.csdn.net/caroline_wendy 错误:android.database.CursorIndexOutOfBoundsException:Index -1 requested, with a size of 1 游标(cursor)的起始位置是-1,不能直接使用. 需要cursor.moveToFirst()或cursor.moveToNext()才能指到第一个值.

android 开发中遇到错误及解决办法总结

新手总结的开发中所遇到错误及解决办法,如有不对,欢迎指正,如有更好的解决办法,也请不吝赐教. 一.dialog.show()引起的android.view.WindowManager$BadTokenException错误 错误日志 android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running?