使用 LiveData 时如何从 Room 检索自动生成的 ID?

How to retrieve auto generated ID from Room when using LiveData?

我正在创建一个 Android 应用程序来存储值列表,例如。特定用户定义名称下不同时间的温度值。我打算使用 SQLite 来存储值,并且我读到使用 Room 会为其提供一个 ORM 层,所以我使用了它。但是后来我 运行 进入了一个异常,基本上说我无法从主线程打开数据库连接,所以我尝试使用 LiveData 进行插入和检索。现在我有 2 tables。我只是想在语法上不准确的情况下展示它们的结构:

**PLACE_DETAILS**
place_id integer auto_increment
place_name string
latitude double
longitude double

**TEMPERATURE_DETAILS**
temperature_id integer auto_increment
place_id foreign key references place_details(place_id)
time_of_record timestamp
temperature float

最初,我想不强制外键关系,只是在插入 PLACE_DETAILS 对象时检索生成的键,就像 Hibernate 所做的那样,并在进一步插入 [=34= 时使用它] table。然而,从这个问题:

我发现 DAO 方法本身需要 return 一个表示生成的 ID 的长值。

@Insert
long insertPlaceDetails(PlaceDetails placeDetails);

但是,在ViewModel中运行的AsyncTask需要重写return.

的doInBackground()方法
public class PlaceDetailsViewModel extends AndroidViewModel {

private final LiveData<List<PlaceDetails>> placeDetailsList;
private PlaceDatabase placeDatabase;

public PlaceDetailsViewModel(@NonNull Application application) {
    super(application);

    placeDatabase = PlaceDatabase.getDatabase(this.getApplication());
    placeDetailsList = placeDatabase.daoAccess().fetchAllPlaceDetails();
}

public LiveData<List<PlaceDetails>> getPlaceDetailsList() {
    return placeDetailsList;
}

public void addPlace(final PlaceDetails placeDetails) {
    Log.d("Adding", "Place: " + placeDetails.getPlaceName());
    new addAsyncTask(placeDatabase).execute(placeDetails);
}

private static class addAsyncTask extends AsyncTask<PlaceDetails, Void, Void> {

    private PlaceDatabase placeDatabase;

    addAsyncTask(PlaceDatabase placeDatabase) {
        this.placeDatabase = placeDatabase;
    }

    @Override
    protected Void doInBackground(PlaceDetails... placeDetails) {
        placeDatabase.daoAccess().insertPlaceDetails(placeDetails[0]);
        return null;
    }
}
}

那么我如何才能在我的代码中实际检索生成的 ID?此外,如果 LiveData 无法为我提供此值并且关系是可行的方法,那么我还如何根据已经自动设置的外键在 TEMPERATURE_DETAILS table 中插入值- 在 PLACE_DETAILS table 中生成?网络上的所有教程都给出了手动给出 id 的示例。

编辑

根据anhtuannd的建议修改了我的VieModelclass。但是被 returned 的值总是-1。这本身表明没有任何内容被插入到数据库中。我的清单中有 WRITE_EXTERNAL_STORAGE 权限。这个工作还需要什么吗?

public class PlaceDetailsViewModel extends AndroidViewModel {

private final LiveData<List<PlaceDetails>> placeDetailsList;
private PlaceDatabase placeDatabase;
private long insertId = -1;

public long getInsertId() {
    return insertId;
}

public PlaceDetailsViewModel(@NonNull Application application) {
    super(application);

    placeDatabase = PlaceDatabase.getDatabase(this.getApplication());
    placeDetailsList = placeDatabase.daoAccess().fetchAllPlaceDetails();
}

public LiveData<List<PlaceDetails>> getPlaceDetailsList() {
    return placeDetailsList;
}

public void onPlaceInserted(long id) {
    insertId = id;
}

public void addPlace(final PlaceDetails placeDetails) {
    Log.d("Adding", "Place: " + placeDetails.getPlaceName());
    new addAsyncTask(placeDatabase).execute(placeDetails);
}

private class addAsyncTask extends AsyncTask<PlaceDetails, Void, Void> {

    private PlaceDatabase placeDatabase;

    addAsyncTask(PlaceDatabase placeDatabase) {
        this.placeDatabase = placeDatabase;
    }

    @Override
    protected Void doInBackground(PlaceDetails... placeDetails) {
        insertId = placeDatabase.daoAccess().insertPlaceDetails(placeDetails[0]);
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        onPlaceInserted(insertId);
    }
}
}

我觉得你可以通过onPostExecute中的回调函数获取ID:

private static class addAsyncTask extends AsyncTask<PlaceDetails, Void, Void> {

    private PlaceDatabase placeDatabase;
    private PlaceDetails place;
    private int insertId = -1;

    addAsyncTask(PlaceDatabase placeDatabase) {
        this.placeDatabase = placeDatabase;
    }

    @Override
    protected Void doInBackground(PlaceDetails... placeDetails) {
        place = placeDetails[0];
        insertId = placeDatabase.daoAccess().insertPlaceDetails(place);
        return null;
    }

     @Override
     protected void onPostExecute(Void result) {
          super.onPostExecute(result);
          onPlaceInserted(insertId, place);
     }
}

void onPlaceInserted(int id, PlaceDetails place) {
    // you get ID here
}