2012-03-17 27 views
0

我跟着一篇關於如何使用android SDK處理SQLite數據庫的教程。我的問題是,當我調用方法「getUsername()」時,應用程序崩潰。我究竟做錯了什麼?SQLiteOpenHelper崩潰Android應用程序

package racenet.racenet; 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 


public class Preferences extends SQLiteOpenHelper { 

    private static final int DATABASE_VERSION = 2; 
    private static final String DATABASE_NAME = "racenet.racenet.db"; 

    Preferences(Context context) { 

     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

     db.execSQL("CREATE TABLE settings(key TEXT, value TEXT)"); 

     values = new ContentValues(); 
     values.put("user_name", ""); 
     getWritableDatabase().insert("settings", null, values); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { 

    } 

    public String getUsername() { 

     Cursor c = getReadableDatabase().query("settings", new String[]{"value"}, 
      "key = 'user_name'", null, null, null, null); 
     c.moveToFirst(); 
     String username = c.getString(0); 
     c.close(); 
     return username; 
    } 
} 
+3

請上傳你的錯誤。 – Lucifer 2012-03-17 09:37:18

回答

3

嗨,試試這個:

@Override 
public void onCreate(SQLiteDatabase db) { 
    db.execSQL("CREATE TABLE settings (key TEXT, value TEXT);"); 

    values = new ContentValues(); 

    // First argument of the put method is a column name 
    // Second argument is an inserted value 
    values.put("key", "user_name"); 
    values.put("value", "user_value"); 

    db.insert("settings", null, values); 
} 

// This method will drop your table and create a new one if you have changed 
// the database version 
@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    db.execSQL("DROP TABLE IF EXISTS settings"); 

    onCreate(db); 
} 
+0

+1好回答..... – MKJParekh 2012-03-17 10:06:55

+0

也添加一些描述與代碼片段..這可以幫助更多:) – MKJParekh 2012-03-17 10:09:54

+0

我也可以建議將表名和列名存儲在類的私有變量中。它將創建更靈活的方式來對將來的數據庫進行更改並編寫選擇/更新/刪除/插入邏輯。 – 2012-03-17 10:19:03

1

有一件事肯定會導致應用程序崩潰,因爲您不關閉在方法中使用的數據庫對象。你需要重寫它這樣:

public String getUsername() { 
    SQLiteDatabase database = getReadableDatabase(); 
    Cursor c = getReadableDatabase().query("settings", new String[]{"value"}, 
     "key = 'user_name'", null, null, null, null); 
    c.moveToFirst(); 
    String username = c.getString(0); 
    c.close(); 
    database.close(); 
    return username; 
} 

編輯擴展我的回答更加完整,使用@slukian觀察:你不應該從onCreateonUpgrade方法中調用getWritableDatabase()getReadableDatabase()。其實你甚至不需要。重寫此方法:

@Override 
public void onCreate(SQLiteDatabase db) { 

    db.execSQL("CREATE TABLE settings(key TEXT, value TEXT)"); 
    values = new ContentValues(); 
    values.put("user_name", ""); 
    db.insert("settings", null, values); 
} 

請注意,我只是用傳入的db對象,就像你上面幾行。

+0

沒有幫助... – 2012-03-17 09:47:38

+0

如果您想幫助您解決問題,您將需要添加錯誤日誌。正如你所看到的,即使沒有這些信息,我們在你的程序中發現了兩個錯誤(你是否看到@slukian評論的編輯?) – 2012-03-17 09:49:33

0

你,因爲你寫的

c.moveToFirst(); 

,不檢查c具有行或沒有得到錯誤..

不管怎麼說.. Ç可是沒有行導致您沒有正確添加行..

只是正確添加值就像中提到的「Taras Feschuk」的回答。

,只要你寫c.moveToFirst() ..first檢查if(c.getCount()>0)