尝试 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);
我有一个简单的 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);