如何将项目添加到子实体,外键引用 Android 房间中的父实体?

How can I add an item to a child entity with foreign key reference to the parent entity in Android Room?

我正在尝试编写一个类似于 Strava 的简单应用程序,它将使用 Room Persistence Library

记录活动

我的两个实体是:

@Entity
public class ActivityRecord {
    @PrimaryKey(autoGenerate = true)
    private long id;
    private Date startTimestamp;
    private Date endTimestamp;

    public ActivityRecord() {
        this.startTimestamp = new Date();
        this.endTimestamp = this.startTimestamp;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Date getStartTimestamp() {
        return startTimestamp;
    }

    public void setStartTimestamp(Date startTimestamp) {
        this.startTimestamp = startTimestamp;
    }

    public Date getEndTimestamp() {
        return endTimestamp;
    }

    public void setEndTimestamp(Date endTimestamp) {
        this.endTimestamp = endTimestamp;
    }
}

和:

@Entity(foreignKeys = @ForeignKey(
    entity = ActivityRecord.class,
    parentColumns = "id",
    childColumns = "recordId",
    onDelete = CASCADE),
    indices = {@Index(value = {"recordId"})})
public class ActivityLocation {

    @PrimaryKey(autoGenerate = true)
    private long id;   
    private double latitude;
    private double longitude;
    private long recordId;


    public ActivityLocation(double latitude, double longitude, long recordId) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.recordId = recordId;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public long getRecordId() { return recordId; }

    public void setRecordId(long recordId) { this.recordId = recordId; }
}

我还创建了这两个 DAO:

@Dao
public interface ActivityRecordDao {
    @Query("SELECT * FROM ActivityRecord ORDER BY id DESC")
    LiveData<List<ActivityRecord>> getActivityRecords();

    @Query("SELECT * FROM ActivityRecord WHERE id = :id")
    ActivityRecord getActivityRecordById(long id);

    @Query("SELECT * FROM ActivityRecord ORDER BY id DESC LIMIT 1")
    ActivityRecord getLastActivityRecord();

    @Insert
    long setActivityRecord(ActivityRecord record);

    @Update
    void updateActivityRecord(ActivityRecord record);

    @Delete
    void deleteActivityRecord(ActivityRecord record);
}

和:

@Dao
public interface ActivityLocationDao {
    @Query("SELECT * FROM ActivityLocation ORDER BY timestamp DESC")
    LiveData<List<ActivityLocation>> getActivityLocations();

    @Query("SELECT * FROM ActivityLocation WHERE id = :id")
    ActivityLocation getActivityLocationById(long id);

    @Query("SELECT * FROM ActivityLocation WHERE recordId = :recordId")
    LiveData<List<ActivityLocation>> getActivityLocationsByRecordId(long recordId);

    @Insert
    void setActivityLocation(ActivityLocation location);

    @Delete
    void deleteActivityLocation(ActivityLocation location);
}

我可以从 MainActivity.java 中插入、更新和删除 ActivityRecords,但我还没有找到如何在我的 BroadcastReceiver 当它从 com.google.android.gms.location.LocationResult

接收到更新的位置数据时

所以,我的问题是,如何添加一个 ActivityLocation 子项并引用一个 ActivityRecord 父项,以及如何在我的 [=18] 中获取我的应用程序数据库的实例=]?

解决了我的 BroadcastReceiver 中的 AsyncTask 问题。

我首先需要传入上下文和 activityLocations 列表作为参数。 这是通过创建私有参数 class 解决的:

private static class ActivityLocationParams {
    Context context;
    List<ActivityLocation> locations;

    ActivityLocationParams(Context context, List<ActivityLocation> locations) {
        this.context = context;
        this.locations = locations;
    }
}

接下来我创建了一个私有的 AsyncTask class:

private static class addActivityLocationAsyncTask extends AsyncTask<ActivityLocationParams, Void, Integer> {
    @Override
    protected Integer doInBackground(ActivityLocationParams... params) {
        Context context = params[0].context;
        List<ActivityLocation> locations = params[0].locations;

        AppDatabase db = AppDatabase.getInstance(context);
        ActivityRecord activityRecord = db.activityRecordDao().getLastActivityRecord();

        int count = 0;
        for (ActivityLocation location : locations) {
            if (activityRecord == null) {
                continue;
            }

            ActivityLocation activityLocation
                    = new ActivityLocation(location.getLatitude(),
                    location.getLongitude(), activityRecord.getId());
            db.activityLocationDao().setActivityLocation(activityLocation);
            count += 1;
        }

        return count;
    }

    @Override
    protected void onPostExecute(Integer count) {
        Log.d(TAG, "Number of ActivityLocations added: " + count.toString());
    }
}

doInBackground 完成后,我打印出添加到数据库中的项目数以供调试之用。

最后我创建了 params 对象并在 BroadcastReceiver 中调用了 AsyncTask:

ActivityLocationParams params = new ActivityLocationParams(context, locations);
new addActivityLocationAsyncTask().execute(params);