问题
Anyone who follows Android tags are probably familiar with me. I am having the hardest time implementing a SQLite database for my highscores. This is also my first time working with SQLite.
I am trying to insert just two variables -- int and long. My insert()
method is not working correctly. Any advice other than the stuff talked about above is also appreciated.
Thank you in advance for your help.
Highscores.java
public class Highscores extends Activity {
DatabaseHelper dh;
SQLiteDatabase db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.highscoresmain);
dh = new DatabaseHelper(this);
dh.openDB(db);
long x = 11;
int y = 22;
TextView rank = (TextView)findViewById(R.id.rank);
TextView percentage = (TextView)findViewById(R.id.percentage);
TextView score = (TextView)findViewById(R.id.score);
TextView r1r = (TextView)findViewById(R.id.r1r);
TextView r1p = (TextView)findViewById(R.id.r1p);
TextView r1s = (TextView)findViewById(R.id.r1s);
dh.insert(x, y, db); //Line 55
scores = dh.getScore(db);
percentages = dh.getPercentage(db);
rank.setText("Rank Column - TEST");
percentage.setText("Percentage Column - TEST ");
score.setText("Score Column - Test");
r1r.setText("test..rank");
r1p.setText("" + percentages);
r1s.setText("test..score");
table = (TableLayout)findViewById(R.id.tableLayout);
dh.closeDB(db);
}
}
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
SQLiteDatabase db;
// Table columns names.
private static final String RANK = "_id";
private static final String SCORE = "score";
private static final String PERCENTAGE = "percentage";
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
}
public SQLiteDatabase openDB(SQLiteDatabase db) {
db = this.getWritableDatabase();
return db;
}
public int getPercentage(SQLiteDatabase db) {
//Cursor c = db.rawQuery("SELECT " + PERCENTAGE + " FROM " + TABLE + " WHERE " + PERCENTAGE + " = " + 22 + ";", null);
Cursor c = db.rawQuery("SELECT " + PERCENTAGE + " FROM " + TABLE + ";", null);
int i = 0;
if(c.getCount() == 0) {
i = 333;
} else if (c.getCount() == 1) {
i = 444;
} else {
i = 888;
/*c.moveToFirst();
int columnIndex = c.getInt(c.getColumnIndex("PERCENTAGE"));
if(columnIndex != -1) {
i = c.getInt(columnIndex);
} else {
i = 999;
}*/
}
c.close();
return i;
}
//Insert new record.
public long insert(long score, int percentage, SQLiteDatabase db) {
ContentValues values = new ContentValues();
values.put(SCORE, score);
values.put(PERCENTAGE, percentage);
return db.insert(TABLE, null, values); //Line 120
}
public synchronized void closeDB(SQLiteDatabase db) {
if(db != null) {
db.close();
}
super.close();
}
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE + " ("
+ RANK + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ SCORE + " LONG,"
+ PERCENTAGE + " INTEGER"
+ ");");
}
LogCat output
01-03 17:09:18.232: E/AndroidRuntime(1712): FATAL EXCEPTION: main
01-03 17:09:18.232: E/AndroidRuntime(1712): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.Highscores}: java.lang.NullPointerException
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.ActivityThread.access$600(ActivityThread.java:141)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.os.Handler.dispatchMessage(Handler.java:99)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.os.Looper.loop(Looper.java:137)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.ActivityThread.main(ActivityThread.java:5039)
01-03 17:09:18.232: E/AndroidRuntime(1712): at java.lang.reflect.Method.invokeNative(Native Method)
01-03 17:09:18.232: E/AndroidRuntime(1712): at java.lang.reflect.Method.invoke(Method.java:511)
01-03 17:09:18.232: E/AndroidRuntime(1712): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-03 17:09:18.232: E/AndroidRuntime(1712): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-03 17:09:18.232: E/AndroidRuntime(1712): at dalvik.system.NativeStart.main(Native Method)
01-03 17:09:18.232: E/AndroidRuntime(1712): Caused by: java.lang.NullPointerException
01-03 17:09:18.232: E/AndroidRuntime(1712): at com.example.test.DatabaseHelper.insert(DatabaseHelper.java:120)
01-03 17:09:18.232: E/AndroidRuntime(1712): at com.example.test.Highscores.onCreate(Highscores.java:55)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.Activity.performCreate(Activity.java:5104)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
01-03 17:09:18.232: E/AndroidRuntime(1712): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
01-03 17:09:18.232: E/AndroidRuntime(1712): ... 11 more
回答1:
On this line, you open the DB:
dh.openDB(db);
This stores the member variable of the database in DatabaseHelper.db
(but nowhere else, and particularly not in Highscores.db
). Then, you call:
dh.insert(x, y, db);
Using a null
db
object from Highscores
. Lastly, within insert()
, you use this null
db
object:
return db.insert(TABLE, null, values);
What you should do instead is use the following as your insert()
method:
public long insert(long score, int percentage) { // Remove db parameter
ContentValues values = new ContentValues();
values.put(SCORE, score);
values.put(PERCENTAGE, percentage);
return db.insert(TABLE, null, values); // This will use the member variable
}
Then, call dh.insert(x, y);
instead.
You should also change openDB(SQLiteDatabase db)
to openDB()
so that it is writing the correct DB; as it stands, it just overwrites the local variable's value (which changes nothing once the function's scope is done).
回答2:
Instead of
dh.openDB(db);
say
db = dh.openDB(db);
(although the openDB
method really doesn't need to have an argument). Your call to openDB
doesn't store the database object reference in db
, so it's NULL when you get around to calling dh.insert(..., db);
.
来源:https://stackoverflow.com/questions/14143886/nullpointerexception-when-trying-to-insert-into-sqlite-android