首页 > 解决方案 > LiveData 返回零而不是正确的整数

问题描述

我正在使用 Room 和 LiveData 在我的应用程序中管理我的 SQLite 数据库。我需要从表中获取一个数据字段,即主键,自动生成的字段。为此,我在我的活动类中编写以下代码:

//Method to insert the new entry in the database
 ViewModelEntry.insert(newEntry);
 ViewModelEntry recentEntry = new ViewModelEntry(RegisterActivity.this.getApplication());

//Observing the LiveData to get the last entry cadID
 recentEntry.getLastEntry().observe(this, lastEntry -> lastCadID = lastEntry.getCadID());
 Toast.makeText(this, "lastCadID = " + lastCadID, Toast.LENGTH_LONG).show();
//This should return the last ID inserted (7, for exemple) but is returning 0 instead

 Intent itemInspectionIntent = new Intent(RegisterActivity.this, InspectionActivity.class);
 itemInspectionIntent.putExtra(MEMORIAL_ITEM_ENTRY, lastCadID);
 startActivity(itemInspectionIntent);

ViewModelEntry我的ViewModel类的实现在哪里,是通过@insert Room方法insert将对象插入数据库的实现。<NewEntry>

编辑:这是<insert>方法的实现>

//ViewModel implementation

//Presented in a code snippet below:
//public static ReportRepository repository;
 public static void insert(SchoolEntry schoolEntry) { repository.insertSchoolEntry(schoolEntry); }

//Repository implementation
public void insertSchoolEntry(SchoolEntry schoolEntry) {
        ReportDatabase.dbWriteExecutor.execute(() -> schoolEntryDao.insertEntry(schoolEntry));
    }

//DAO Implementation
    @Insert()
    void insertEntry(SchoolEntry schoolEntry);

这是该方法<dbWriteExecutor>的 Repository 实现中出现的实现<insertSchoolEntry>:(这个在我的 Database 类中实现):

public static final ExecutorService dbWriteExecutor = Executors.newFixedThreadPool(NUMBER_THREADS);
//NUMBER_THREADS = 4

编辑结束

当我尝试获取<cadID>刚刚插入的条目的字段值时,就会出现问题。出于某种原因,此代码返回 0 而不是最后一个条目的值。

这些是<getLastEntry>我的 ViewModel、Repository 和 DAO 中方法的实现:

//ViewModel implementation
public static ReportRepository repository;

public ViewModelEntry(@NonNull Application application) {
        super(application);
        repository = new ReportRepository(application); }

 public LiveData<SchoolEntry> getLastEntry() {return repository.getLastSchoolEntry(); }


//Repository Implementation
private SchoolEntryDao schoolEntryDao;

public ReportRepository(Application application) {
        ReportDatabase db = ReportDatabase.getDatabase(application);
        schoolEntryDao = db.schoolEntryDao(); }

public LiveData<SchoolEntry> getLastSchoolEntry() { return schoolEntryDao.getLastEntry(); }


//DAO Implementation

@Query("SELECT * FROM SchoolEntry WHERE cadID == (SELECT MAX(cadID) from SchoolEntry)")
    LiveData<SchoolEntry> getLastEntry();

插入过程完美无缺,因为我使用数据库检查器检查条目是否已插入。此外,当我在数据库检查器中运行该 SQLite 查询时,它确实给了我刚刚记录在我的数据库中的条目。有人可以帮我解决这种情况吗?

标签: javaandroidsqliteandroid-room

解决方案


发生了什么?

插入发生在后台线程中,我们不等待插入完成。这导致cadId在插入之前获取最后一个,这导致 0 值。

建议的解决方案

  1. 进入后台线程
  2. 执行插入ViewModelEntry.insert(newEntry);并等待它完成。
  3. 获取最后插入的项目"SELECT * FROM SchoolEntry WHERE cadID == (SELECT MAX(cadID) from SchoolEntry)"。将 Dao LiveData 连接到recentEntry,这已经在主线程上观察到了。

推荐阅读