手动实现Realm数据库自增ID添加数据时触发NumberFormatException问题求助
解决Realm自增ID实现中的NumberFormatException错误
嘿,我一眼就看出问题出在哪了——你遇到的java.lang.NumberFormatException,是因为你错误地把Realm查询返回的Results<UserInfo>对象直接转成字符串去解析成整数,而那个字符串其实是Realm对象的调试描述文本(就是你看到的[UserInfo = [{Id:null},{username:null},{password:null},{type:null}]]),这根本不是数字,肯定转失败呀!
先分析你代码里的核心问题:
- 你先创建了
UserInfo对象,但此时它的Id是null,用endsWith("Id", userInfo.Id)查询完全没有意义,而且Realm的findAll()永远不会返回null,哪怕没数据也会返回空的Results对象。 - 试图把
Results对象直接转成字符串来获取最大ID,这完全是错误的实现方式。
正确的自增ID实现方案
我推荐把Id字段改成Integer类型(更适合自增逻辑,还能避免字符串转数字的各种坑),同时加上@PrimaryKey注解确保ID唯一,下面是完整的修改方案:
1. 修改UserInfo实体类
public class UserInfo extends RealmObject { @PrimaryKey // 标记为主键,保证ID唯一 private Integer id; // 改成Integer类型,更适合自增场景 private String username; private String password; private String type; // Getter & Setter 方法 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
2. 修改添加按钮的点击事件代码
add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { realm.beginTransaction(); // 查询当前表中最大的ID值 Number maxId = realm.where(UserInfo.class).max("id"); // 计算新ID:如果表为空就从0开始,否则在最大ID基础上加1 int newId = (maxId == null) ? 0 : maxId.intValue() + 1; // 直接用带主键的方式创建对象(Realm支持这种写法) UserInfo userInfo = realm.createObject(UserInfo.class, newId); // 设置其他字段值 userInfo.setUsername(username.getText().toString()); userInfo.setPassword(password.getText().toString()); userInfo.setType(dropdown.getSelectedItem().toString()); realm.commitTransaction(); Toast.makeText(Add.this,"Username and Password Saved",Toast.LENGTH_LONG).show(); Intent toMain = new Intent(Add.this, List.class); startActivity(toMain); } });
如果你坚持要用String类型的ID(不推荐)
如果因为某些原因必须保留String类型的ID,那可以这样修改点击事件,避免异常:
add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { realm.beginTransaction(); // 按ID降序排序,取最后一条数据(也就是ID最大的那条) UserInfo lastUser = realm.where(UserInfo.class).sort("Id", Sort.DESCENDING).findFirst(); int newIdInt; if (lastUser == null) { newIdInt = 0; } else { try { // 把String类型的ID转成整数再加1 newIdInt = Integer.parseInt(lastUser.getId()) + 1; } catch (NumberFormatException e) { // 处理ID不是有效数字的异常,这里可以给个默认值或者提示用户 newIdInt = 0; e.printStackTrace(); } } String newId = String.valueOf(newIdInt); UserInfo userInfo = realm.createObject(UserInfo.class); userInfo.setId(newId); userInfo.setUsername(username.getText().toString()); userInfo.setPassword(password.getText().toString()); userInfo.setType(dropdown.getSelectedItem().toString()); realm.commitTransaction(); Toast.makeText(Add.this,"Username and Password Saved",Toast.LENGTH_LONG).show(); Intent toMain = new Intent(Add.this, List.class); startActivity(toMain); } });
最后提醒
使用数字类型的主键是更合理的选择:既避免了字符串转数字的异常风险,也能让Realm的查询和主键操作更高效,还能保证ID的唯一性。
内容的提问来源于stack exchange,提问作者user6677716
相关产品推荐
相关产品推荐

