[英]Android Room Database Issues
我試圖在 class 練習中完成這個小練習,我們必須使用房間數據庫保存數據,然后在 ListView 中顯示該信息。
這個應用程序是關於一個玩家的。 玩家有 4 個字段(Id、Name、Position、進球數)。
第一個保存的玩家的 ID 應該是 #1,第二個玩家的 ID 應該是 #2,依此類推。
用戶必須通過 EditText 字段輸入播放器的名稱。
然后有三個單選按鈕,用戶必須選擇 select 一個才能選擇他們的 position(守門員、防守、前鋒)。 最后,用戶必須使用 EditText 字段輸入該球員的進球數。
最后,用戶必須使用 EditText 字段輸入該球員的進球數。
一旦用戶單擊“保存”按鈕,之前選擇的所有字段都將被清除,它們將是一條顯示玩家 ID# 的快速吐司消息。
為了查看所有保存的數據,用戶必須單擊“查看全部”按鈕,這會將他們帶到第二個活動並顯示球員的姓名,Position,在下一個活動中得分的進球數。
我對房間不太熟悉,所以每當我按下“保存”保存按鈕時,我的應用程序就會崩潰。 任何幫助將不勝感激,謝謝!
MainActivity.Java
public class MainActivity extends AppCompatActivity {
private EditText playerEdt, goalsEdt;
private int id = 0;
private RadioGroup groupRad;
private RadioButton radioButton;
private MyDatabase myDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerEdt = findViewById(R.id.edtPlayer);
goalsEdt = findViewById(R.id.edtGoals);
myDb = MyDatabase.getInstance(MainActivity.this);
}
public void saveData(View view) {
id++;
String name = playerEdt.getText().toString();
groupRad = findViewById(R.id.radGroup);
int selectedId = groupRad.getCheckedRadioButtonId();
radioButton = findViewById(selectedId);
String position = radioButton.getText().toString();
String goalsString = goalsEdt.getText().toString();
int goals = Integer.valueOf(goalsString);
Player player = new Player(id, name, position, goals);
myDb.playerDao().insert(player);
playerEdt.setText("");
goalsEdt.setText("");
groupRad.clearCheck();
}
public void viewData(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
}
第二活動.Java
public class SecondActivity extends AppCompatActivity {
ListView listView;
MyDatabase database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
listView = findViewById(R.id.listView);
database = MyDatabase.getInstance(SecondActivity.this);
List<Player> players = database.playerDao().getAll();
ArrayAdapter adapter = new ArrayAdapter(SecondActivity.this, android.R.layout.simple_list_item_1, players);
listView.setAdapter(adapter);
}
}
播放器.Java
@Entity
public class Player {
@PrimaryKey
private int id;
@ColumnInfo(name = "player_name")
private String name;
@ColumnInfo(name = "player_position")
private String position;
@ColumnInfo(name = "player_goals")
private int goals;
public Player(int id, String name, String position, int goals) {
this.id = id;
this.name = name;
this.position = position;
this.goals = goals;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public int getGoals() {
return goals;
}
public void setGoals(int goals) {
this.goals = goals;
}
}
PlayerDao.java
@Dao
public abstract class PlayerDao {
@Insert
public abstract void insert (Player player);
@Delete
public abstract void delete (Player player);
@Update
public abstract void update (Player player);
@Query("select * from Player")
public abstract List<Player> getAll();
}
MyDatabase.Java
@Database(entities = Player.class, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract PlayerDao playerDao();
private static MyDatabase instance;
public static MyDatabase getInstance(Context context){
if( instance == null){
instance = Room.databaseBuilder(context, MyDatabase.class, "PlayerDb")
.allowMainThreadQueries()
.build();
}
return instance;
}
}
activity_main.xml: https://www.codepile.net/pile/d5rq8mx2
activity_second.xml: https://www.codepile.net/pile/2vbYzXq3
看來您有許多問題:-
您需要為 Player class 的所有成員設置吸氣劑。
添加了這些(和設置器):-
public int getGoals() {
return goals;
}
public void setGoals(int goals) {
this.goals = goals;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
核心問題是在saveData中查找視圖的嘗試返回空值,因此您會收到 null 指針異常 (NPE),因為視圖不存在於 SAVE 按鈕中。
解決方案是查找視圖(即在 onCreate 方法中使用 findViewById)。
缺乏數據驗證也會導致問題。 以下版本的 MainActivity.java 處理問題:-
public class MainActivity extends AppCompatActivity {
private EditText playerEdt, goalsEdt;
private int id = 0;
private RadioGroup groupRad;
private RadioButton radioButton;
private MyDatabase myDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerEdt = findViewById(R.id.edtPlayer);
goalsEdt = findViewById(R.id.edtGoals);
groupRad = findViewById(R.id.radGroup);
myDb = MyDatabase.getInstance(MainActivity.this);
}
public void saveData(View view) {
id++;
String name = playerEdt.getText().toString();
if (name.length() < 1) {
Toast.makeText(view.getContext(),"Player Name is blank. Try again.",Toast.LENGTH_SHORT).show();
playerEdt.requestFocus();
}
radioButton = findViewById(groupRad.getCheckedRadioButtonId());
if (radioButton == null) {
Toast.makeText(view.getContext(),"You must select Goalie Defence or Forward. Try again",Toast.LENGTH_SHORT).show();
return;
}
String position = radioButton.getText().toString();
String goalsString = goalsEdt.getText().toString();
int goals = 0;
try {
goals = Integer.valueOf(goalsString);
} catch (Exception e) {
Toast.makeText(view.getContext(),"You must give the number of Goals. try again.",Toast.LENGTH_SHORT).show();
goalsEdt.requestFocus();
}
Player player = new Player(id, name, position, goals);
if (myDb.playerDao().insert(player) < 1) {
Toast.makeText(view.getContext(),"Player not Added (duplicate)",Toast.LENGTH_SHORT).show();
return;
}
playerEdt.setText("");
goalsEdt.setText("");
groupRad.clearCheck();
Toast.makeText(view.getContext(),"Player Added. Name is " + name + " Position is " + position + " Goals = " + goals,Toast.LENGTH_SHORT).show();
}
public void viewData(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
}
此外,PlayerDao.java 已更改為在播放器名稱重復時不會失敗,並且在插入、刪除或更新時也返回有用的值。 這是:-
@Dao
public abstract class PlayerDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
public abstract long insert (Player player);
@Delete
public abstract int delete (Player player);
@Update
public abstract int update (Player player);
@Query("select * from Player")
public abstract List<Player> getAll();
}
首先,如果您在 Player.java id
中使用autoGenerate = true
會更好:
@Entity
public class Player {
@PrimaryKey(autoGenerate = true)
private int id;
通過這樣做,您不必給您的玩家 ID,Room 會為您完成這項工作。
並且對於保存時應用崩潰,您必須檢查日志並查看導致應用崩潰的原因。 更新您的問題,以便用戶可以幫助您。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.