简体   繁体   English

Android 房间数据库问题

[英]Android Room Database Issues

I'm trying to complete this small in class exercise where we have to save data using Room Database and then display that information in a ListView.我试图在 class 练习中完成这个小练习,我们必须使用房间数据库保存数据,然后在 ListView 中显示该信息。

This app is about a player.这个应用程序是关于一个玩家的。 The player has 4 fields (Id, Name, Position, Number of Goals scored).玩家有 4 个字段(Id、Name、Position、进球数)。

  • The ID of the very first player saved should be #1, #2 for the second player and so on.第一个保存的玩家的 ID 应该是 #1,第二个玩家的 ID 应该是 #2,依此类推。

  • The user must enter the name of the player through the EditText field.用户必须通过 EditText 字段输入播放器的名称。

  • There are then three radio buttons of which, the user has to select one in order to choose their position (Goalie, Defence, Forward).然后有三个单选按钮,用户必须选择 select 一个才能选择他们的 position(守门员、防守、前锋)。 Finally, the last field the user must enter the number of goals this player has scored through the use of the EditText field.最后,用户必须使用 EditText 字段输入该球员的进球数。

  • Finally, the last field the user must enter the number of goals this player has scored through the use of the EditText field.最后,用户必须使用 EditText 字段输入该球员的进球数。

Once the user clicks the "SAVE" button, all the fields previously selected will be cleared and their will be a quick toast message displaying the ID# of the player.一旦用户单击“保存”按钮,之前选择的所有字段都将被清除,它们将是一条显示玩家 ID# 的快速吐司消息。

In order to view all the saved data the user must click the "VIEW ALL" button which will take them to the second activity and display the Name of the Player, Position, Number of Goals scored in the next activity.为了查看所有保存的数据,用户必须单击“查看全部”按钮,这会将他们带到第二个活动并显示球员的姓名,Position,在下一个活动中得分的进球数。

I'm not too familiar with room so whenever I press the "Save"Save button my app crashes.我对房间不太熟悉,所以每当我按下“保存”保存按钮时,我的应用程序就会崩溃。 Any help would be greatly appreciated, Thanks!任何帮助将不胜感激,谢谢!

MainActivity.Java 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);
}
}

SecondActivity.Java第二活动.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);
}
}

Player.Java播放器.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 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 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_main.xml: https://www.codepile.net/pile/d5rq8mx2

activity_second.xml: https://www.codepile.net/pile/2vbYzXq3 activity_second.xml: https://www.codepile.net/pile/2vbYzXq3

It would appear that you have a number of issues:-看来您有许多问题:-

You need to have getters for all the members of the Player class.您需要为 Player class 的所有成员设置吸气剂。

These were added (and setters):-添加了这些(和设置器):-

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;
}

The core issue is that the attemps to find the views in the saveData is returning nulls and hence you are getting a null pointer exception (NPE) because the views don't exist within the SAVE button.核心问题是在saveData中查找视图的尝试返回空值,因此您会收到 null 指针异常 (NPE),因为视图不存在于 SAVE 按钮中。

The solution is to find the views (ie use findViewById in the onCreate method).解决方案是查找视图(即在 onCreate 方法中使用 findViewById)。

There is also a lack of data verification which will causes issue.缺乏数据验证也会导致问题。 The following version of MainActivity.java handles the issues:-以下版本的 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);
    }
}

Additionally PlayerDao.java has been changed to not fail if the player name is duplicated and to also return useful values when inserting, deleting or updating.此外,PlayerDao.java 已更改为在播放器名称重复时不会失败,并且在插入、删除或更新时也返回有用的值。 it is:-这是:-

@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();

}

First of all, it would be better if you use autoGenerate = true in your Player.java class for id :首先,如果您在 Player.java id中使用autoGenerate = true会更好:

@Entity
public class Player {
@PrimaryKey(autoGenerate = true)
private int id;  

By doing this you don't have to give your players ids and Room does the job for you.通过这样做,您不必给您的玩家 ID,Room 会为您完成这项工作。

And for the app crash when saving, you must check the log and see what is causing the app to crash.并且对于保存时应用崩溃,您必须检查日志并查看导致应用崩溃的原因。 Update your question with that so users can help you.更新您的问题,以便用户可以帮助您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM