所以我一直在设置一个SQL Databse的单词,就我从调试日志中可以看出的情况而言,它实际上确实可以加载和设置。但是,当我试图查询它时,无论它是处于设置过程还是已经完成,我的程序因为异常而被强制关闭。日志的调查显示这一点:Android中神秘的SQLiteBindOrColumnOutOfRangeException。
07-12 13:47:02.000: W/dalvikvm(5247): threadid=1: thread exiting with uncaught exception
(group=0x40a401f8)
...
07-12 13:47:02.010: E/AndroidRuntime(5247): Caused by:
android.database.sqlite.SQLiteBindOrColumnIndexOutOfRangeException: bind or column index out of
range: handle 0x14a6548
...
07-12 14:41:36.250: E/AndroidRuntime(6326): at com.example.wordsearchandroid.WordListProvider.query(WordListProvider.java:70)
在Android API一个搜索SQLiteBindOrColumnIndexOutOfRangeException的揭示了一个非常简朴的...页面(http://developer.android.com/reference/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException .html)没有提到“句柄”指的是什么。
不幸的是,据我所知,我的查询中没有任何东西指的是不存在的列。这是我的ContentProvider我的查询方法:
public class WordListProvider extends ContentProvider {
private WordListOpenHelper listOpenHelper;
....
public static final String ID = "_ID";
public static final String WORD = "WORD";
public static final String LENGTH = "LENGTH";
...
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
qBuilder.setTables(DB_NAME);
Cursor c;
switch(matcher.match(uri)) {
case SEARCH_WORD_LIST:
Log.d("WORDLISTPROVIDER", "Entered Search");
c = qBuilder.query(listOpenHelper.getReadableDatabase(), projection, null,
selectionArgs, null, null, null);
Log.d("WORDLISTPROVIDER", "Query Completed");
if (c == null)
return null;
c.setNotificationUri(getContext().getContentResolver(), uri);
break;
default:
Log.d("WORDLISTPROVIDER", "Default Entered");
throw new IllegalArgumentException("Unknown URI " + uri);
}
Log.d("WORDLISTPROVIDER", "Exited Search");
return c;
}
^唯一的例外发生在该行
c = qBuilder.query(listOpenHelper.getReadableDatabase(), projection, null,
selectionArgs, null, null, null);
供参考,在这里是如何为这个特定呼叫投影和selectionArgs两个字符串设定:
String[] proj = {
WordListProvider.ID,
WordListProvider.WORD
};
String[] selectionArgs = {""};
这里是我的数据库的构建器,它是WordListProvider中的内部类:
private static class WordListOpenHelper extends SQLiteOpenHelper {
private SQLiteDatabase wordDb;
private Context helperContext;
private static final String WORD_LIST_CREATE = "CREATE TABLE "+ DB_NAME +
" (" +
ID + " INTEGER PRIMARY KEY, " +
WORD + " TEXT, " +
LENGTH + " INTEGER " +
");";
WordListOpenHelper(Context context) {
super(context, "wordlist", null, 1);
helperContext = context;
Log.d("OPENHELPER", "Constructed");
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("OPENHELPER", "Creating");
wordDb = db;
Log.d("OPENHELPER", "DB set");
wordDb.execSQL(WORD_LIST_CREATE);
Log.d("OPENHELPER", "SQL Execed");
loadWordList();
}
private void loadWordList() {
new Thread(new Runnable() {
public void run() {
try {
loadWords();
} catch (IOException e) {
Log.d("OPENHELPER", "Exception Caught");
throw new RuntimeException(e);
}
}
}).start();
}
private void loadWords() throws IOException {
...
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
...
}
}
loadWords最终会完成,但是我得到异常,无论表是否已完成加载(有时表不会完成加载,我会得到异常,程序将退出。表格将完成加载)。此外,我的列名是一致的,至少它们在表面上似乎是 - 如果我向查询传递投影的null(即返回所有行),甚至会发生异常;任何人有任何可能导致异常的想法,或者处理意味着什么?
是的,做它。 API参考文件没有提到这一点,而API指南则完全相反。谢谢。 – user1521682 2012-07-13 19:02:35
完成。如何将问题标记为已回答? – user1521682 2012-07-16 15:16:10
谢谢,我不知道我是否理解你的问题,但你可以阅读关于接受问题[这里](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-工作) – Leszek 2012-07-16 20:57:55