繁体   English   中英

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

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

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

**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所做的那样),并在进一步插入TEMPERATURE_DETAILS表中使用它时,才检索生成的键。 但是,从这个问题来看:

Room API-如何获取实体最近插入的生成ID?

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

@Insert
long insertPlaceDetails(PlaceDetails placeDetails);

但是,在ViewModel中运行的AsyncTask需要重写以Void作为返回值的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无法为我提供此值并且关系是解决方法,那么我又如何根据PLACE_DETAILS表中自动生成的外键在TEMPERATURE_DETAILS表中插入值? 网络上的所有教程都提供了示例,这些示例中已经手动给出了ID。

编辑

根据anhtuannd给出的建议,我修改了VieModel类。 但是,返回的值始终为-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
}

暂无
暂无

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

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