博观而约取,厚积而薄发。这篇文章主要讲述如何将项目添加到具有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 = https://www.songbingjia.com/android/{"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问题。
【如何将项目添加到具有Android Room中父实体的外键引用的子实体()】我首先需要将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静态BroadcastReceiver无法正常工作
- APPWIDGET_UPDATE奥利奥兼容性
- AlarmManager和BroadcastReceiver的LocalNotification未在Android O(oreo)中启动
- Android - 使用广播接收器重新加载活动
- HM10与Arduino和Android BLE之间的蓝牙低功耗大数据传输
- 不运行时接收消息,Xamarin Android上的显式广播和隐式广播
- 即使屏幕在Android中被锁定,也会启动活动屏幕
- CONNECTIVITY_CHANGE在Android N的目标中已弃用
- Android - 启动时启动服务