我的数据库中有两个表,用户和播放器。 用户注册/登录并添加玩家。 用户ID是玩家表中使用的外键。 我的代码运行良好,可以完美保存所有内容。 但是我的模拟器出现问题,它一直崩溃,所以我擦除了内存并重新运行了我的应用程序。 现在我遇到一个问题,当我注册/登录并添加播放器时,代码会运行并在调试模式下看起来很好,但是数据库中的表永远不会填充
对此我感到非常愤怒,因为它在清除内存之前一直可以100%正常工作。 有人可以提供一些支持吗?
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
// Database information
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "MyDB1.db";
private static final String TABLE_USER = "User";
private static final String TABLE_PLAYERS = "Player";
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
// Field names for Users
private static final String COLUMN_USER_NAME = "User_name";
private static final String COLUMN_USER_ID = "User_id";
private static final String COLUMN_USER_EMAIL = "User_email";
private static final String COLUMN_USER_PASSWORD = "User_password";
// Field names for Players
public static final String COLUMN_PLAYER_NAME = "Player_name";
public static final String COLUMN_PLAYER_AGE = "Player_age";
public static final String COLUMN_PLAYER_WEIGHT = "Player_weight";
public static final String COLUMN_PLAYER_HEIGHT = "Player_height";
public static final String COLUMN_PLAYER_ID = "Player_id";
public static final String FOREIGN_PLAYER_ID = COLUMN_USER_ID;
// private static final Image COLUMN_PLAYER_IMAGE ;
public static final String[] ALL_KEYS = new String[]{COLUMN_PLAYER_NAME, COLUMN_PLAYER_AGE, COLUMN_PLAYER_HEIGHT, COLUMN_PLAYER_WEIGHT};
// Table 1 : Login/Register
private String CREATE_USER_TABLE = "CREATE TABLE " + TABLE_USER + "(" + COLUMN_USER_NAME + " TEXT,"
+ COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_USER_EMAIL + " TEXT," + COLUMN_USER_PASSWORD + " TEXT" + ")";
// Table 2 : Adding players
private String CREATE_PLAYER_TABLE = "CREATE TABLE " + TABLE_PLAYERS + "(" + COLUMN_PLAYER_NAME + " TEXT,"
+ COLUMN_PLAYER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_PLAYER_AGE + " INTEGER," + COLUMN_PLAYER_WEIGHT + " INTEGER," + COLUMN_PLAYER_HEIGHT + " INTEGER, " + FOREIGN_PLAYER_ID + " INTEGER," + "FOREIGN KEY(" + FOREIGN_PLAYER_ID + ") REFERENCES " + TABLE_USER + "(User_id) " + ")";
// Drop tables
private String DROP_USER_TABLE = "DROP TABLE IF EXISTS " + TABLE_USER;
private String DROP_PLAYER_TABLE = "DROP TABLE IF EXISTS " + TABLE_PLAYERS;
public DatabaseHelper(Context context) {
//String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
if (!db.isReadOnly()) {
// Enable foreign key constraints
db.execSQL("PRAGMA foreign_keys=ON;");
}
}
public DatabaseHelper open() {
db = this.getReadableDatabase();
return this;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_USER_TABLE);
db.execSQL(CREATE_PLAYER_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DROP_USER_TABLE);
db.execSQL(DROP_PLAYER_TABLE);
onCreate(db);
}
// Adding a user to Users table
public void addUser(User user) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// Table 1 : Add users info
values.put(COLUMN_USER_NAME, user.getName());
values.put(COLUMN_USER_EMAIL, user.getEmail());
values.put(COLUMN_USER_PASSWORD, user.getPassword());
values.put(FOREIGN_PLAYER_ID, user.getForeignID());
db.insert(TABLE_USER, null, values);
db.close();
}
// Adding a player to players table
public void addPlayer(Player player) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// Table 2 : Add players info
values.put(COLUMN_PLAYER_NAME, player.getPlayerName());
values.put(COLUMN_PLAYER_AGE, player.getPlayerAge());
values.put(COLUMN_PLAYER_HEIGHT, player.getPlayerHeight());
values.put(COLUMN_PLAYER_WEIGHT, player.getPlayerWeight());
values.put("Foreign_id", player.getForeignKey());
db.insert(TABLE_PLAYERS, null, values);
db.close();
}
// Checking the users email
public boolean checkUser(String email) {
String[] columns = {
COLUMN_USER_ID
};
SQLiteDatabase db = this.getWritableDatabase();
String selection = COLUMN_USER_EMAIL + " = ?";
String[] selectionArgs = {email};
Cursor cursor = db.query(TABLE_USER,
columns,
selection,
selectionArgs,
null,
null,
null);
int cursorCount = cursor.getCount();
cursor.close();
db.close();
if (cursorCount > 0) {
return true;
}
return false;
}
//
public String getColumnUserName(String email) {
String user = "";
String[] columns = {
COLUMN_USER_ID
};
SQLiteDatabase db = this.getWritableDatabase();
String selection = COLUMN_USER_EMAIL + " = ?";
String[] selectionArgs = {email};
Cursor cursor = db.query(TABLE_USER,
columns,
selection,
selectionArgs,
null,
null,
null);
int cursorCount = cursor.getCount();
String[] b = cursor.getColumnNames();
if (cursor.moveToFirst()) // data?{
user = cursor.getString(cursor.getColumnIndex("User_id"));
cursor.close(); // that's important too, otherwise you're gonna leak cursors
db.close();
if (cursorCount > 0) {
return user;
}
return user;
}
// Checking the users email and password
public boolean checkUser(String email, String password) {
String[] columns = {
COLUMN_USER_ID
};
SQLiteDatabase db = this.getWritableDatabase();
String selection = COLUMN_USER_EMAIL + " = ?" + " AND " + COLUMN_USER_PASSWORD + " =?";
String[] selectionArgs = {email, password};
Cursor cursor = db.query(TABLE_USER,
columns,
selection,
selectionArgs,
null,
null,
null);
int cursorCount = cursor.getCount();
cursor.close();
db.close();
if (cursorCount > 0) {
return true;
}
return false;
}
public Cursor getAllRows(){
SQLiteDatabase db = this.getReadableDatabase();
//String query = "SELECT * from "+TABLE_PLAYERS;
Cursor cursor = db.rawQuery("select Player_id _id, * from Player" , null);
return cursor;
}
}
AddPlayers.java
public class addPlayers extends AppCompatActivity implements
View.OnClickListener {
private Button insert;
private static final int PICK_IMAGE = 100;
private final AppCompatActivity activity = addPlayers.this;
private EditText editTextPlayerName;
private EditText editTextPlayerAge;
private EditText editTextPlayerWeight;
private EditText editTextPlayerHeight;
private TextInputEditText textInputEditTextEmail;
private Inputvalidation inputvalidation;
private DatabaseHelper databaseHelper;
private Player player;
private Button appCompatButtonRegister;
private User user;
DatabaseHelper myDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_players);
// insert = (Button) findViewById(R.id.profilePicture);
// insert.setOnClickListener(new View.OnClickListener()
//getPlayersInformationListView();
getSupportActionBar().hide();
initViews();
initListeners();
initObjects();
}
private void initViews() {
editTextPlayerName = (EditText) findViewById(R.id.playerName);
editTextPlayerAge = (EditText) findViewById(R.id.playerAge);
editTextPlayerHeight = (EditText) findViewById(R.id.playerHeight);
editTextPlayerWeight = (EditText) findViewById(R.id.playerWeight);
textInputEditTextEmail = (TextInputEditText) findViewById(R.id.enterEmail);
appCompatButtonRegister = (Button) findViewById(R.id.savePlayer);
}
private void initListeners() {
appCompatButtonRegister.setOnClickListener(this);
}
private void initObjects() {
inputvalidation = new Inputvalidation(activity);
databaseHelper = new DatabaseHelper(activity);
player = new Player();
}
// Table 2 : Add players info
@Override
public void onClick(View v) {
// Intent intent = new Intent(Intent.ACTION_PICK, Uri.parse("content://media/internal/images/media"));
//startActivityForResult(intent, PICK_IMAGE);
switch (v.getId()) {
case R.id.savePlayer:
postDataToSQLite();
break;
}
}
private void postDataToSQLite() {
if (!databaseHelper.checkUser(editTextPlayerName.getText().toString().trim()))
//textInputEditTextPassword.getText().toString().trim()))
{
Bundle email = getIntent().getExtras();
String a = databaseHelper.getColumnUserName(email.getString("EMAIL"));
player.setPlayerName(editTextPlayerName.getText().toString().trim());
player.setPlayerAge(Integer.parseInt(editTextPlayerAge.getText().toString().trim()));
player.setPlayerHeight(Integer.parseInt(editTextPlayerHeight.getText().toString().trim()));
player.setPlayerWeight(Integer.parseInt(editTextPlayerWeight.getText().toString().trim()));
player.setForeignKey(Integer.parseInt(a));
databaseHelper.addPlayer(player);
Intent accountIntent = new Intent(activity, Players.class);
startActivity(accountIntent);
}
}
}
Players.java
public class Players extends AppCompatActivity {
private Button insert;
private static final int PICK_IMAGE = 100;
private String nameFromIntent = "";
DatabaseHelper myDb;
ListView playersList;
ArrayList<String> listItem;
ArrayAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_players);
openDB();
getAllRows();
myDb = new DatabaseHelper(this);
//Open add players section
insert = (Button) findViewById(R.id.addPlayer);
insert.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
openAddPlayersActivity();
}
});
}
private void openDB() {
myDb = new DatabaseHelper(this);
myDb.open();
}
private void closeDB() {
myDb.close();
}
private void getAllRows() {
Cursor cursor = myDb.getAllRows();
// Allow activity to manage lifetime of cursor
// Deprecated
startManagingCursor(cursor);
// Setup mapping from cursor to view fields
String[] fromFieldNames = new String[]
{DatabaseHelper.COLUMN_PLAYER_NAME, DatabaseHelper.COLUMN_PLAYER_AGE, DatabaseHelper.COLUMN_PLAYER_WEIGHT, DatabaseHelper.COLUMN_PLAYER_HEIGHT};
int[] toViewIDs = new int[]{R.id.textView01, R.id.textView02, R.id.textView5, R.id.textView6};
// Create Adapter to map columns of DB onto elements in the UI
SimpleCursorAdapter myCursorAdapter = new SimpleCursorAdapter(
this, R.layout.player_layout, cursor , fromFieldNames , toViewIDs);
// Set the adapter for the list view
ListView myList = (ListView) findViewById(R.id.playersList);
myList.setAdapter(myCursorAdapter);
}
private void openAddPlayersActivity(){
Intent intent = new Intent(this, addPlayers.class);
String nameFromIntent = getIntent().getStringExtra("EMAIL");
intent.putExtra(("EMAIL"), nameFromIntent);
startActivity(intent);
}
}
答案 0 :(得分:1)
也许您在DatabaseHelper类中传递了错误的模型。
public void addUser(User user){
//code..
}
public void add player(Player player){
/* Are you sure you have created Player.java model?? Because you have another class Players.java too. And check for User.java model too..
another thing, make sure your model have default constructors. */
//code..
}
答案 1 :(得分:1)
我认为您的问题是您尝试使用 User_id 列(FK)而不是引用的User_id使用 User_name 添加玩家。然后,这将导致以下结果:-
04-12 08:25:34.782 13798-13798/aaa.so55497937 E/SQLiteLog: (787) abort at 16 in [INSERT INTO Player(Player_age,Player_name,User_id,Player_weight,Player_height) VALUES (?,?,?,?,?)]: FOREIGN KEY constraint failed
04-12 08:25:34.783 13798-13798/aaa.so55497937 E/SQLiteDatabase: Error inserting Player_age=21 Player_name=Fred User_id=FRED Player_weight=75 Player_height=160
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1471)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
at aaa.so55497937.DatabaseHelper.addPlayer(DatabaseHelper.java:125)
即User_id = FRED不会与用户表中引用的User_ID列中的任何值相关(由于使用INTEGER PRIMARY KEY进行定义,因此该值始终为数字(不需要PS AUTOINCREMENT,实际上浪费资源{{ 3}}))
也就是说,您使用:-
为播放器设置了ForeignID。String a = databaseHelper.getColumnUserName(email.getString("EMAIL"));
同时应在用户的user_id列中设置 a 。因此,也许添加方法:-
public String getColumnUserId(String email) {
String rv = "";
String[] columns = {COLUMN_USER_ID};
String selection = COLUMN_USER_EMAIL + "=?";
String[] selectionArgs = {email};
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.query(TABLE_USER,columns,selection,selectionArgs,null,null,null);
if (cursor.moveToFirst()) {
rv = cursor.getString(cursor.getColumnIndex(COLUMN_USER_ID));
}
cursor.close();
db.close();
return rv;
}
然后使用:-
String a = databaseHelper.getColumnUserId(email.getString("EMAIL"));
也许会注意到,如果一切都没有按预期进行,尤其是使用SQLite时,则应检查日志(即,尽管已记录该错误,但仍会捕获并忽略该错误,因此不会崩溃)。