如何将项目添加到具有Android Room中父实体的外键引用的子实体?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将项目添加到具有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);
}
我可以从ActivityRecords
插入,更新和删除MainActivity.java
,但我还没有发现当我从ActivityLocation
收到更新的位置数据时,如何在我的BroadcastReceiver
中插入带有外键引用的新com.google.android.gms.location.LocationResult
所以,我的问题是,如何添加一个ActivityLocation
子项目参考ActivityRecord
父项目,如何在我的BroadcastReceiver
中获取我的应用程序数据库的实例?
解决了我的BroadcastReceiver中的AsyncTask问题。
我首先需要将activityLocations的上下文和列表作为参数传递。通过创建私有params类解决了这个问题:
private static class ActivityLocationParams {
Context context;
List<ActivityLocation> locations;
ActivityLocationParams(Context context, List<ActivityLocation> locations) {
this.context = context;
this.locations = locations;
}
}
接下来我创建了一个私有的AsyncTask类:
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);
以上是关于如何将项目添加到具有Android Room中父实体的外键引用的子实体?的主要内容,如果未能解决你的问题,请参考以下文章
Android:如何使 Kotlin 中所有对象列表的类型转换器(用于 Room)通用
TypeConverter() 在 Android 中的 Room 出现 TypeConverter 错误时具有私有访问权限
仅具有本地 Room 数据库的 Android Paging v3:如何滚动到分页列表中的特定位置?
如何将 Not Null 表列迁移到 Android Room 数据库中的 Null