前几天在写一个小项目的时候,使用到了Android的sqlite数据库,有关于sqlite数据库的使用方法,大家可以百度,这里就不不再赘述。当我从数据库中取出数据后,用for循环遍历游标的时候,程序闪!退!了!!,我的老天鹅!for循环竟然出错了,赶紧看了一下错误日志,发现是在游标中取数据的时候超出了游标的界限,也就是说所取的位置超出了游标中的总数,但是使用moveToNext没有问题!这就很奇怪了,在这里先不卖关子,经过我的猜测和百度以及官方文档,最终知道了问题的出处,就是游标的move方法,cursor.move()方法是根据当前位置移动的数量,而不是从第一条移动到指定位置。下图是官方说明:
(从当前位置移动光标相对大小,向前或向后移动。)之前一直以为是后者。
什么意思呢,怎么证明呢,爬坑之旅开始,首先Android项目,创建数据库辅助类DataBaseHelper并且继承SQLiteOpenHelper,在初次加载程序时创建test测试表,并且插入10条数据,10条数据从0到9,该表中只有一个字段:
package com.example.sqlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class DataBaseHelper extends SQLiteOpenHelper {
/**
* @param context
* 上下文
* @param name
* 数据库名字
* @param factory
* 游标,当我们传入null时代表使用系统自带的CursorFactory
* @param version
* 版本
*/
Context context;
public DataBaseHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
this.context = context;
}
/**
* 在首次加载程序时,创建所需要的表
*/
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
try {
arg0.execSQL("create table test (num varchar(20))");
arg0.execSQL("insert into test values ('0')");
arg0.execSQL("insert into test values ('1')");
arg0.execSQL("insert into test values ('2')");
arg0.execSQL("insert into test values ('3')");
arg0.execSQL("insert into test values ('4')");
arg0.execSQL("insert into test values ('5')");
arg0.execSQL("insert into test values ('6')");
arg0.execSQL("insert into test values ('7')");
arg0.execSQL("insert into test values ('8')");
arg0.execSQL("insert into test values ('9')");
} catch (Exception e) {
// TODO: handle exception
Toast.makeText(context, "数据库创建失败" + e, 1).show();
}
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
}
然后在activity中放置一个button按钮,用于点击它获取数据
然后在点击事件中获取数据库中的值并且从小到大排序,然后使用for循环将i和对应取出来的数字打印出来
SQLiteDatabase sqLiteDatabase = dataBaseHelper
.getReadableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("select * from test order by num",
null);
cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
Log.e("i", i + "");
cursor.move(i);
Log.e("num", cursor.getString(0));
}
好,开始运行程序,你会发现程序闪退了,这个时候看打印的log日志,
当i等于0的时候,取得是0,当i等于1的时候,取得值是1,到现在好像还没出现什么问题,但是再接着往下看,当i等于2的时候,取得值是3!什么,3不应该是在第四个位置吗,也就是应该当i等于4的时候,再往下看,当i真正的等于4的时候,会发现,程序异常了,常了,了……,查看错误信息报CursorIndexOutOfBoundsException异常,超出了CursorI的大小。
这个时候我们在来分析一下上面打印的log日志,当一、(i=0,num=0),二(i=1,num=1),三、(i=2,num=3),四、(i=3,num=5),有没有发现规律,那就是本次的num加下一次i等于下一次的num,即一里面的num加二里面的i等于二里面的num,以此类推,由此便可证明move是根据当前位置向前或者向后移动指定位数。
好了,当然我当时没有来得及查看文档,使用的是moveToNext()方法,个人推荐使用此方法,省事方便安全,当然如果这篇文章有什么错误之处,还请指正,谢谢。多学习,多总结。
转载请注明出处啊,谢谢