NullPointerException when trying to insert into SQ

2019-02-28 12:58发布

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

2条回答
在下西门庆
2楼-- · 2019-02-28 13:51

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).

查看更多
【Aperson】
3楼-- · 2019-02-28 13:54

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);.

查看更多
登录 后发表回答