2012-03-17 47 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)