尝试 return SQLite 数据库中的对象时出现 NullPointer

NullPointer when trying to return Object from SQLite database

我有一个简单的 android 应用程序,它接收 2 个玩家名称,然后启动 GameActivity activity。

游戏activity是一款简单的井字游戏。当 2 名玩家完成游戏时,它应该将数据库中的获胜者 'wins' 增加 1,对于失败者 'losses' 也是如此。

在我的结束游戏功能中,当玩家在一行中获得 3 个 X 或 Os 时调用,我正在写

        Player player1;
        player1 = db.returnPlayerByName(player_one);
        db.insertWinnerScore(player1);

db 在 ScoreDB class(SQLite 数据库)的实例中。在那个 class 中,我有一个 'returnPlayerByName' 方法接收用户名(字符串)和一个 'getPlayerFromCursor' 方法接收来自 returnPlayerByName 方法的光标。

    public Player returnPlayerByName(String name){
    String where = PLAYER_NAME + "=?";
    String[] whereArgs = {name};

    this.openReadableDB();
    try {
        Cursor cursor = db.query(PLAYER_TABLE, null, where, whereArgs, null, null, null);
        cursor.moveToFirst();
        Player player = getPlayerFromCursor(cursor);
        if (cursor != null){
            cursor.close();
        }

        this.closeDB();
        return player;
    } catch (Exception e){
        Log.d("PlayerApp", "Exception " + e);
        return null;
    }

}

private static Player getPlayerFromCursor(Cursor cursor) {
    if (cursor == null || cursor.getCount() == 0){
        return null;
    }
    else {
        try {
            Player player = new Player(
                    cursor.getInt(PLAYER_ID_COL),
                    cursor.getString(PLAYER_NAME_COL),
                    cursor.getInt(WINS_COL),
                    cursor.getInt(LOSSES_COL),
                    cursor.getInt(TIES_COL));
            return player;
        }
        catch(Exception e) {
            Log.d("PlayerApp", "Exception " + e);
            return null;
        }
    }
}

我的错误如下

java.lang.NullPointerException: Attempt to invoke virtual method 'com.mad.playerappcos.Player com.mad.playerappcos.ScoreDB.returnPlayerByName(java.lang.String)' on a null object reference

我当然理解错误,我只是不明白为什么该方法会捕获异常。可能是一些小东西,但我已经看了几个小时了,但没有解决方案。

如有任何帮助,我们将不胜感激!

package com.mad.playerappcos;

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

import java.util.ArrayList;

/**
 * Created by oshau on 10/02/2018.
 */

public class ScoreDB {

    public static final String DB_NAME = "score.db";
    public static final int DB_VERSION = 1;

    public static final String PLAYER_TABLE = "player";

    public static final String PLAYER_ID = "_id";
    public static final int PLAYER_ID_COL = 0;

    public static final String PLAYER_NAME = "player_name";
    public static final int PLAYER_NAME_COL = 1;

    public static final String WINS = "wins";
    public static final int WINS_COL = 2;

    public static final String LOSSES = "losses";
    public static final int LOSSES_COL = 3;

    public static final String TIES = "ties";
    public static final int TIES_COL = 4;

    public static final String DROP_PLAYER_TABLE =
            "DROP TABLE IF EXISTS " + PLAYER_TABLE;

    public static final String CREATE_PLAYER_TABLE =
            "CREATE TABLE " + PLAYER_TABLE + " (" +
            PLAYER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            PLAYER_NAME + " TEXT UNIQUE, " +
            WINS + " INT, " +
            LOSSES + " INT, " +
            TIES + " INT)";


    private static class DBHelper extends SQLiteOpenHelper {

        public DBHelper(Context context, String name,
                        CursorFactory factory, int version) {
            super(context, name, factory, version);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // create tables
            db.execSQL(CREATE_PLAYER_TABLE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        }

    }
    private SQLiteDatabase db;
    private DBHelper dbHelper;

    public ScoreDB(Context context){
        dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION);
    }

    private void openReadableDB() {
        db = dbHelper.getReadableDatabase();
    }

    private void openWriteableDB() {
        db = dbHelper.getWritableDatabase();
    }

    private void closeDB() {
        if (db != null)
            db.close();
    }

    public long insertPlayer(Player player){
        ContentValues cv = new ContentValues();
        cv.put(PLAYER_NAME, player.getName());
        cv.put(WINS, player.getWins());
        cv.put(LOSSES, player.getLosses());
        cv.put(TIES, player.getTies());

        this.openWriteableDB();
        long rowID = db.insert(PLAYER_TABLE, null, cv);

        return rowID;
    }

    public ArrayList<Player> getPlayers() {
        ArrayList<Player> players = new ArrayList<Player>();
        openReadableDB();
        Cursor cursor = db.query(PLAYER_TABLE,
                null, null, null, null, null, null);
        while (cursor.moveToNext()) {
            Player player = new Player();
            player.setPlayerID(cursor.getInt(PLAYER_ID_COL));
            player.setName(cursor.getString(PLAYER_NAME_COL));
            player.setWins(cursor.getInt(WINS_COL));
            player.setLosses(cursor.getInt(LOSSES_COL));
            player.setTies(cursor.getInt(TIES_COL));

            players.add(player);
        }
        cursor.close();
        closeDB();
        return players;
    }
    public ArrayList<String> getPlayerNames() {
        ArrayList<String> players = new ArrayList<String>();
        openReadableDB();
        Cursor cursor = db.query(PLAYER_TABLE,
                null, null, null, null, null, null);
        while (cursor.moveToNext()) {
            Player player = new Player();
            player.setPlayerID(cursor.getInt(PLAYER_ID_COL));
            player.setName(cursor.getString(PLAYER_NAME_COL));
            player.setWins(cursor.getInt(WINS_COL));
            player.setLosses(cursor.getInt(LOSSES_COL));
            player.setTies(cursor.getInt(TIES_COL));

            players.add(player.getName());
        }
        cursor.close();
        closeDB();
        return players;
    }

    public void insertWinnerScore(Player player){

        String where = PLAYER_NAME + "= ?";
        String[] whereArgs = {player.getName()};
        ContentValues cv = new ContentValues();
        cv.put(WINS, getCurrentWins(player) + 1);

        this.openWriteableDB();
        db.update(PLAYER_TABLE, cv, where, whereArgs);

    }

    public void insertLoserScore(Player player){

        String where = PLAYER_NAME + "= ?";
        String[] whereArgs = {player.getName()};
        ContentValues cv = new ContentValues();
        cv.put(WINS, getCurrentLosses(player) + 1);

        this.openWriteableDB();
        db.update(PLAYER_TABLE, cv, where, whereArgs);

    }

    public void insertTieScore(Player player){

        String where = PLAYER_NAME + "= ?";
        String[] whereArgs = {player.getName()};
        ContentValues cv = new ContentValues();
        cv.put(WINS, getCurrentTies(player) + 1);

        this.openWriteableDB();
        db.update(PLAYER_TABLE, cv, where, whereArgs);

    }


    public Player returnPlayerByName(String name){
        String where = PLAYER_NAME + "=?";
        String[] whereArgs = {name};

        this.openReadableDB();
        try {
            Cursor cursor = db.query(PLAYER_TABLE, null, where, whereArgs, null, null, null);
            cursor.moveToFirst();
            Player player = getPlayerFromCursor(cursor);
            if (cursor != null){
                cursor.close();
            }

            this.closeDB();
            return player;
        } catch (Exception e){
            Log.d("PlayerApp", "Exception " + e);
            return null;
        }

    }

    private Player getPlayerFromCursor(Cursor cursor) {
        if (cursor == null || cursor.getCount() == 0){
            return null;
        }
        else {
            try {
                Player player = new Player(
                        cursor.getInt(PLAYER_ID_COL),
                        cursor.getString(PLAYER_NAME_COL),
                        cursor.getInt(WINS_COL),
                        cursor.getInt(LOSSES_COL),
                        cursor.getInt(TIES_COL));
                return player;
            }
            catch(Exception e) {
                Log.d("PlayerApp", "Exception " + e);
                return null;
            }
        }
    }
}

问题似乎是调用 returnPlayerByName 调用时 db 为空。

db 设置为 SCoreDB class 的实例应该可以解决此问题。例如:-

    db = new ScoreDB(this); //<<<< ADDED note! assumes within an activity
    Player player1;
    player1 = db.returnPlayerByName(player_one);
    db.insertWinnerScore(player1);