Android Room数据库插入数据后无ID,重启应用才出现的问题咨询
问题分析与解决方案
这个问题其实是Room数据库的常见行为,原因很明确:Room的@Insert操作不会自动更新你传入的实体对象的主键ID——哪怕你给主键加了autoGenerate = true的自增配置也一样。
具体原因拆解
你现在的代码里,调用insertMention(mention)后直接读取mention.id,这时候这个id还是你创建对象时的默认值(比如0或者null)。因为Room执行插入时,只会把数据写入数据库并返回生成的主键ID,但不会主动修改你内存中那个mention对象的字段值。
而当你重启应用后,重新从数据库查询这个对象时,拿到的是数据库里已经分配好自增ID的实体,所以ID就正常显示了。
修复方案
只需要两步就能解决问题:
修改Dao的插入方法,让它返回插入的主键ID
你的Dao里的insertMention方法需要返回long类型(对应自增主键的数值类型),示例代码如下:@Dao public interface MentionDao { @Insert long insertMention(Mention mention); // 返回插入行的自增ID }插入后手动将返回的ID赋值给mention对象
调用插入方法时接收返回的ID,然后把它设置到你的mention对象上,这样后续使用这个对象就能拿到正确的ID了:// 替换原来的insert调用逻辑 long insertedId = mentionDataBase.mentionDao().insertMention(mention); mention.id = insertedId; // 如果你的id是私有字段,就用setId(insertedId)方法赋值 // 现在再Toast就能显示正确的ID了 Toast.makeText(DeterminigMentionActivity.this, mention.id+"", Toast.LENGTH_LONG).show();
额外提醒
如果你的Dao插入方法是异步的(比如用了协程suspend或者RxJava的Single),一定要在异步回调/协程作用域里处理返回的ID,不能在主线程同步调用后立即获取,否则会因为插入操作还未完成而拿到错误的值。从你的代码来看是同步调用,所以上面的方案完全适用。
内容的提问来源于stack exchange,提问作者Abolfazl
相关产品推荐
相关产品推荐

