Mates在通过NDK使用sqlite3本机c库(JNI)时收到此错误消息
请建议我在哪里做错了
01-29 11:04:19.532: E/Error(2023): SQLite3.Exception: database disk image is malformed
01-29 11:04:19.544: E/dalvikvm(2023): JNI ERROR (app bug): accessed stale local reference 0x7f00001d (index 7 in a table of size 7)
01-29 11:04:19.544: E/dalvikvm(2023): VM aborting
01-29 11:04:19.544: A/libc(2023): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 2023 (abdkosh.android)
这是我生成此错误的代码块
public ArrayList<String> getDefinations(String query, int column_index)
{
ArrayList<String> words = new ArrayList<String>();
MatrixCursor mcursor = null;
try {
Stmt stmt = getDB2().prepare(query);
if (stmt.step()) {
stmt.get_cursor().moveToFirst();
mcursor = stmt.get_cursor();
try {
mcursor.moveToFirst();
do {
words.add(mcursor.getString(column_index));
} while (mcursor.moveToNext());
} catch (IndexOutOfBoundsException e) {
if (MainActivity.logcat_status) {
Log.e("Error", e + "");
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
if (MainActivity.logcat_status) {
Log.e("Error", e + "");
}
}
这是我试图执行的查询
“选择pos,定义,样本FROM word INNER JOIN sense ON word.wordid = sense.wordid INNER JOIN synset ON sense.synsetid = synset.synsetid LEFT JOIN示例ON sample.synsetid = synset.synsetid WHERE lemma ='life'“
实际上,“生命”这个词并不在字典中,所以
stmt.get_cursor().moveToFirst();
转到第一个记录集(第1行),它实际上没有退出,在此行之后通过异常,应用程序被dalvikvm关闭。
在这种情况下,情况正是如此。
所以我的问题是“stmt”如何知道没有特定单词的记录集。
这是我下载并使用jni(c)包装器类的链接 http://www.sqlite.org/snapshot/sqlite-amalgamation-201401290146.zip 然后通过NDK创建“libsqlite3_jni.so”文件
处理程序类的链接,使用http://code.google.com/p/sqlite3-android/进行c代码交互。
IMO stmt.step()方法仅在没有记录集时才会出现问题。
这是我完整的Stmt.java
package SQLite3;
import com.shabdkosh.android.MainActivity;
import android.util.Log;
/**
* Class to represent compiled SQLite3 statement.
*
* Note, that all native methods of this class are not synchronized, i.e. it is
* up to the caller to ensure that only one thread is in these methods at any
* one time.
*/
public class Stmt {
/**
* Internal handle for the SQLite3 statement.
*/
private long handle = 0;
/**
* Internal last error code for prepare()/step() methods.
*/
protected int error_code = 0;
/**
* Prepare the next SQL statement for the Stmt instance.
*
* @return true when the next piece of the SQL statement sequence has been
* prepared, false on end of statement sequence.
*/
public native boolean prepare() throws SQLite3.Exception;
/**
* Perform one step of compiled SQLite3 statement.
*
* Example:<BR>
*
* <PRE>
* ...
* try {
* Stmt s = db.prepare("select * from x; select * from y;");
* s.bind(...);
* ...
* s.bind(...);
* while (s.step(cb)) {
* Object o = s.value(...);
* ...
* }
* // s.reset() for re-execution or
* // s.prepare() for the next piece of SQL
* while (s.prepare()) {
* s.bind(...);
* ...
* s.bind(...);
* while (s.step(cb)) {
* Object o = s.value(...);
* ...
* }
* }
* } catch (SQLite.Exception e) {
* s.close();
* }
* </PRE>
*
* @return true when row data is available, false on end of result set.
*/
public native boolean step() throws SQLite3.Exception;
/**
* Close the compiled SQLite3 statement.
*/
public native void close() throws SQLite3.Exception;
/**
* Reset the compiled SQLite3 statement without clearing parameter bindings.
*/
public native void reset() throws SQLite3.Exception;
/**
* Clear all bound parameters of the compiled SQLite3 statement.
*/
public native void clear_bindings() throws SQLite3.Exception;
/**
* Bind positional integer value to compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
* @param value
* value of parameter
*/
public native void bind(int pos, int value) throws SQLite3.Exception;
/**
* Bind positional long value to compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
* @param value
* value of parameter
*/
public native void bind(int pos, long value) throws SQLite3.Exception;
/**
* Bind positional double value to compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
* @param value
* value of parameter
*/
public native void bind(int pos, double value) throws SQLite3.Exception;
/**
* Bind positional byte array to compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
* @param value
* value of parameter, may be null
*/
public native void bind(int pos, byte[] value) throws SQLite3.Exception;
/**
* Bind positional String to compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
* @param value
* value of parameter, may be null
*/
public native void bind(int pos, String value) throws SQLite3.Exception;
/**
* Bind positional SQL null to compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
*/
public native void bind(int pos) throws SQLite3.Exception;
/**
* Bind positional zero'ed blob to compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
* @param length
* byte size of zero blob
*/
public native void bind_zeroblob(int pos, int length)
throws SQLite3.Exception;
/**
* Return number of parameters in compiled SQLite3 statement.
*
* @return int number of parameters
*/
public native int bind_parameter_count() throws SQLite3.Exception;
/**
* Return name of parameter in compiled SQLite3 statement.
*
* @param pos
* parameter index, 1-based
* @return String parameter name
*/
public native String bind_parameter_name(int pos) throws SQLite3.Exception;
/**
* Return index of named parameter in compiled SQLite3 statement.
*
* @param name
* of parameter
* @return int index of parameter, 1-based
*/
public native int bind_parameter_index(String name)
throws SQLite3.Exception;
/**
* Retrieve integer column from exec'ed SQLite3 statement.
*
* @param col
* column number, 0-based
* @return int column value
*/
public native int column_int(int col) throws SQLite3.Exception;
/**
* Retrieve long column from exec'ed SQLite3 statement.
*
* @param col
* column number, 0-based
* @return long column value
*/
public native long column_long(int col) throws SQLite3.Exception;
/**
* Retrieve double column from exec'ed SQLite3 statement.
*
* @param col
* column number, 0-based
* @return double column value
*/
public native double column_double(int col) throws SQLite3.Exception;
/**
* Retrieve blob column from exec'ed SQLite3 statement.
*
* @param col
* column number, 0-based
* @return byte[] column value
*/
public native byte[] column_bytes(int col) throws SQLite3.Exception;
/**
* Retrieve string column from exec'ed SQLite3 statement.
*
* @param col
* column number, 0-based
* @return String column value
*/
public native String column_string(int col) throws SQLite3.Exception;
/**
* Retrieve column type from exec'ed SQLite3 statement.
*
* @param col
* column number, 0-based
* @return column type code, e.g. SQLite.Constants.SQLITE_INTEGER
*/
public native int column_type(int col) throws SQLite3.Exception;
/**
* Retrieve number of columns of exec'ed SQLite3 statement.
*
* @return int number of columns
*/
public native int column_count() throws SQLite3.Exception;
/**
* Retrieve column data as object from exec'ed SQLite3 statement.
*
* @param col
* column number, 0-based
* @return Object or null
*/
public Object column(int col) throws SQLite3.Exception {
switch (column_type(col)) {
case Constants.SQLITE_INTEGER:
return new Long(column_long(col));
case Constants.SQLITE_FLOAT:
return new Double(column_double(col));
case Constants.SQLITE_BLOB:
return column_bytes(col);
case Constants.SQLITE3_TEXT:
return column_string(col);
}
return null;
}
/**
* Return name of column of SQLite3 statement.
*
* @param col
* column number, 0-based
* @return String or null
*/
public native String column_name(int col) throws SQLite3.Exception;
/**
* Return table name of column of SQLite3 statement.
*
* @param col
* column number, 0-based
* @return String or null
*/
public native String column_table_name(int col) throws SQLite3.Exception;
/**
* Return database name of column of SQLite3 statement.
*
* @param col
* column number, 0-based
* @return String or null
*/
public native String column_database_name(int col) throws SQLite3.Exception;
/**
* Return declared column type of SQLite3 statement.
*
* @param col
* column number, 0-based
* @return String or null
*/
public native String column_decltype(int col) throws SQLite3.Exception;
/**
* Return origin column name of column of SQLite3 statement.
*
* @param col
* column number, 0-based
* @return String or null
*/
public native String column_origin_name(int col) throws SQLite3.Exception;
/**
* Return statement status information.
*
* @param op
* which counter to report
* @param flg
* reset flag
* @return counter
*/
public native int status(int op, boolean flg);
/**
* Destructor for object.
*/
protected native void finalize();
/**
* Internal native initializer.
*/
private static native void internal_init();
static {
internal_init();
}
protected String[] mColumns = null;
public String[] column_names(){
if(mColumns == null){
int colCount = 0;
try {
colCount = column_count();
} catch (Exception e1) {
// TODO Auto-generated catch block
if(MainActivity.logcat_status){
Log.e("Error", e1+"");}
}
mColumns = new String[colCount];
for(int i=0; i<colCount;i++){
try {
mColumns[i] = column_name(i);
} catch (Exception e) {
// TODO Auto-generated catch block
if(MainActivity.logcat_status){
Log.e("Error", e+"");}
}
}
}
return mColumns;
}
public int column_index(String col_name){
String[] names = column_names();
int col_count = names.length;
int i;
for(i=0; i < col_count; i++){
if(col_name.equals(names[i])) return i;
}
return -1;
}
public MatrixCursor get_cursor(){
return get_cursor(20);
}
public MatrixCursor get_cursor(int capacity){
MatrixCursor cursor = new MatrixCursor(column_names(), capacity);
try {
int colCount = column_count();
while(step()){
Object[] rowObject = new Object[colCount];
for(int i=0; i < colCount; i++){
rowObject[i] = column_string(i);
}
cursor.addRow(rowObject);
}
} catch (Exception e) {
// TODO Auto-generated catch block
if(MainActivity.logcat_status){
Log.e("Error", e+"");}
}
return cursor;
}
}
提前致谢
答案 0 :(得分:0)
@Manish。我已经编辑了您的示例代码。请像这样使用cursor.getCount()。三江源
public ArrayList<String> getDefinations(String query, int column_index)
{
ArrayList<String> words = new ArrayList<String>();
MatrixCursor mcursor = null;
try
{
Stmt stmt = getDB2().prepare(query);
if (stmt.step())
{
//stmt.get_cursor().moveToFirst();
mcursor = stmt.get_cursor();
if(mcursor != null && mcursor.getCount() > 0)
{
try
{
mcursor.moveToFirst();
do
{
words.add(mcursor.getString(column_index));
}
while (mcursor.moveToNext());
}
catch (IndexOutOfBoundsException e)
{
if (MainActivity.logcat_status)
{
Log.e("Error", e + "");
}
}
}
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
if (MainActivity.logcat_status)
{
Log.e("Error", e + "");
}
}
}