2014-01-09 71 views
0

我需要在我的android应用程序上使用SQLite数据库,但是当我尝试打开它时,它崩溃了,我找不到原因。我在过去的一个小时里看了一下网络,但有点找不到任何帮助。SQLite数据库崩溃打开

下面是代码:

public class PrivDB { 

public static final String KEY_ROWID = "_id"; 
public static final String KEY_LEVEL = "level"; 
public static final String KEY_LOCKED = "locked"; 
public static final String KEY_SEQUENCE = "sequence"; 
public static final String KEY_TRIES = "tries"; 

private static final String DATABASE_NAME = "patdb"; 
private static final String DATABASE_TABLE = "tablename"; 
private static final int DATABASE_VERSION = 1; 

private DbHelper ourHelper; 
private Context ourContext; 
private SQLiteDatabase ourDatabase; 

private static class DbHelper extends SQLiteOpenHelper { 

    public DbHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     // TODO Auto-generated constructor stub 
    } 

    @Override 
    public void onCreate(SQLiteDatabase arg0) { 
     // TODO Auto-generated method stub 
     arg0.execSQL("CREATE TABLE " + DATABASE_TABLE + " ("+ 
        KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "+ 
        KEY_LEVEL + " STRING NOT NULL, " + 
        KEY_LOCKED + " INTEGER NOT NULL, " + 
        KEY_SEQUENCE + " INTEGER NOT NULL, "+ 
        KEY_TRIES + " INTEGER NOT NULL);"); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { 
     // TODO Auto-generated method stub 
     arg0.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE); 
     onCreate(arg0); 
    } 

} 

public PrivDB (Context c) { 
    ourContext = c; 
} 

public PrivDB open() throws SQLException { 
    ourHelper = new DbHelper(ourContext); 
    ourDatabase = ourHelper.getWritableDatabase(); 
    return this; 
} 

public void close(){ 
    ourHelper.close(); 
} 

public long createEntry (String level, int locked, int sequence, int tries){ 
    ContentValues cv = new ContentValues(); 
    cv.put(KEY_LEVEL, level); 
    cv.put(KEY_LOCKED, locked); 
    cv.put(KEY_SEQUENCE, sequence); 
    cv.put(KEY_TRIES, tries); 
    return ourDatabase.insert(DATABASE_TABLE, null, cv); 
} 

public String getData() { 
    String[] columns = new String[]{KEY_ROWID, KEY_LEVEL, KEY_LOCKED, KEY_SEQUENCE, KEY_TRIES}; 
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null); 
    String result = ""; 

    int iRow = c.getColumnIndex(KEY_ROWID); 
    int iLevel = c.getColumnIndex(KEY_LEVEL); 
    int iLocked = c.getColumnIndex(KEY_LOCKED); 
    int iSequence = c.getColumnIndex(KEY_SEQUENCE); 
    int iTries = c.getColumnIndex(KEY_TRIES); 

    for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){ 
     result = result + c.getString(iRow) + " " + c.getString(iLevel) + " " + c.getString(iLocked) + " " 
       + c.getString(iSequence) + c.getString(iTries) + "\n"; 
    } 

    return result; 
} 

public int getLocked(String s) throws SQLException { 
    String[] columns = new String[]{KEY_ROWID, KEY_LEVEL, KEY_LOCKED, KEY_SEQUENCE, KEY_TRIES}; 
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_LEVEL + "=" + s, null, null, null, null); 
    if(c != null){ 
     c.moveToFirst(); 
     int locked = c.getInt(2); 
     return locked; 
    } 
    return (Integer) null; 
} 

public void updateEntry(String s, int locked, int tries) throws SQLException { 
    ContentValues cvUpdate = new ContentValues(); 
    cvUpdate.put(KEY_LOCKED, locked); 
    cvUpdate.put(KEY_TRIES, tries); 
    ourDatabase.update(DATABASE_TABLE, cvUpdate, KEY_LEVEL + "=" + s, null); 
} 

} 

和我是怎么调用数据库:

public class Stats extends Activity { 

TextView tv; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.stats); 
    tv = (TextView) findViewById(R.id.tvStats); 
    PrivDB info = new PrivDB(this); 
    info.open(); 
    String data = info.getData(); 
    info.close(); 
    tv.setText(data); 
} 

} 

当我打开Stats类,应用程序崩溃,但如果我注释掉info.open()直到info.close()然后它工作正常(但显然没有任何反应)。

UPDATE

这里是日志猫输出:

01-09 13:16:32.786: E/AndroidRuntime(517): FATAL EXCEPTION: main 
01-09 13:16:32.786: E/AndroidRuntime(517): java.lang.RuntimeException: Unable to start activity  ComponentInfo{com.docime.vamoose.patternz/com.docime.vamoose.patternz.Stats}:  java.lang.StringIndexOutOfBoundsException 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.app.ActivityThread.access$2300(ActivityThread.java:125) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.os.Handler.dispatchMessage(Handler.java:99) 
01-09 13:16:32.786: E/AndroidRuntime(517): at android.os.Looper.loop(Looper.java:123) 
01-09 13:16:32.786: E/AndroidRuntime(517): at android.app.ActivityThread.main(ActivityThread.java:4627) 
01-09 13:16:32.786: E/AndroidRuntime(517): at java.lang.reflect.Method.invokeNative(Native  Method) 
01-09 13:16:32.786: E/AndroidRuntime(517): at java.lang.reflect.Method.invoke(Method.java:521) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
01-09 13:16:32.786: E/AndroidRuntime(517): at dalvik.system.NativeStart.main(Native Method) 
01-09 13:16:32.786: E/AndroidRuntime(517): Caused by: java.lang.StringIndexOutOfBoundsException 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.app.ContextImpl.validateFilePath(ContextImpl.java:1579) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:539) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  com.docime.vamoose.patternz.PrivDB.open(PrivDB.java:60) 
01-09 13:16:32.786: E/AndroidRuntime(517): at  com.docime.vamoose.patternz.Stats.onCreate(Stats.java:18) 
01-09 13:16:32.786: E/AndroidRuntime(517): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
01-09 13:16:32.786: E/AndroidRuntime(517): at    android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
01-09 13:16:32.786: E/AndroidRuntime(517): ... 11 more 
+2

如果发生崩溃,logcat中会出现异常stacktrace。请将其包含在问题中。 – laalto

+2

好的,你根据邹邹的评论更新了代码 - 还有问题吗? – laalto

+1

将STRING更改为TEXT。在onCreate()中。 –

回答

1

你从来没有通过DATABASE_TABLE名称或代码,你分配给它。这就是它崩溃的原因。

private static final String DATABASE_TABLE = "TABLE_NAME"; 

更新:请更新您的onCreate()。 SQLite的询问服务TEXT instedOf String

@Override 
public void onCreate(SQLiteDatabase arg0) { 
    // TODO Auto-generated method stub 
    arg0.execSQL("CREATE TABLE " + DATABASE_TABLE + " ("+ 
       KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "+ 
       KEY_LEVEL + " TEXT NOT NULL, " + 
       KEY_LOCKED + " INTEGER NOT NULL, " + 
       KEY_SEQUENCE + " INTEGER NOT NULL, "+ 
       KEY_TRIES + " INTEGER NOT NULL);"); 
} 

另一个重要的事情要传递的背景之下,使用静态变量不会保存。 你应该使用像下面

private static Context ourContext; 

public PrivDB (Context c) { 
    this.ourContext = c; 
} 

但最重要的,因为你所面对的错误/异常

产生的原因:java.lang.StringIndexOutOfBoundsException,

Thrown when the a string is indexed with a value less than zero, or greater than or equal to the size of the array

我会要求你检查以下 - java.lang.StringIndexOutOfBoundsException: index=0 length=0 in get sqlite database

+0

忘了在帖子中添加那些,它是在课堂上,但它仍然崩溃 – VaMoose

+0

@VaMoose - 请检查更新。 – Yup

0

变化STRINGTEXT以下

arg0.execSQL("CREATE TABLE " + DATABASE_TABLE + " ("+ 
       KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "+ 
       KEY_LEVEL + " STRING NOT NULL, " + 
       KEY_LOCKED + " INTEGER NOT NULL, " + 
       KEY_SEQUENCE + " INTEGER NOT NULL, "+ 
       KEY_TRIES + " INTEGER NOT NULL);"); 

NOTE :变化后,请添加一个到你的数据库版本

0

我觉得您的信息指向空 试试这个代码:

if (null != info) 
{ 
    info.open(); 
    String data = info.getData(); 
    info.close(); 
}else 
Log.d("App Name", "Info is null"); 

getData()函数的另外一件事是您正在读取数据库 所以您应该以读模式打开数据库。

ourDatabase = ourHelper.getWritableDatabase(); To 
ourDatabase = ourHelper.getReadableDatabase(); 
0

此行KEY_TRIES + " INTEGER NOT NULL);");有两个; .Does你的表中获取创建/填充?

+0

你从哪里得到';'两次。仔细检查rawSQL,最后一个是关闭'arg0.execSQL()'。 – Yup

+0

'由java.lang.StringIndexOutOfBoundsException引起的'这可能意味着表没有被创建,或者他引用了错误的列。而对于rawSQL,';'不使用IMO。我一直使用没有';'和完美的作品。 – PsyGik

+0

你可以请结帐以下文档教程,rawSQL';'是不是例外 - http://developer.android.com/guide/topics/data/data-storage.html#db – Yup