Android Room - 使用自动生成获取新插入行的 id - MVVM 版本
Posted
技术标签:
【中文标题】Android Room - 使用自动生成获取新插入行的 id - MVVM 版本【英文标题】:Android Room - Get the id of new inserted row with auto-generate - MVVM Version 【发布时间】:2020-12-18 06:54:06 【问题描述】:正如这里android Room - Get the id of new inserted row with auto-generate 所讨论的,可以从新插入的对象中获取 ID。
但是如何以 MVVM 模式从 DAO 到我的 Activity 类获取这个 ID?
那里的一些answers 建议使用rxjava 和类似的东西:return Single.fromCallable<Long> recipesDao.insertManual(cookingRecipes)
但是为了一个方法调用而实现两个完整的 Gradle 依赖是否有意义?
难道没有办法让我目前的结构能够做到这一点吗?
Activity - ViewModel - Repository (-AsyncTask) - Dao
唯一的问题是从插入语句中获取返回值,该语句是从AsyncTask
调用的:
private static class UpdateChallengeInfosAsyncTask extends AsyncTask<ChallengeInfos, Void, Void>
private ChallengeInfosDao mAsyncTaskDao;
UpdateChallengeInfosAsyncTask(ChallengeInfosDao dao)
mAsyncTaskDao = dao;
@Override
protected Void doInBackground(ChallengeInfos... challengeInfos)
mAsyncTaskDao.insert(challengeInfos[0]);
return null;
也许可以像这里一样使用onPostExecute()
+ Interface
组合?How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
【问题讨论】:
AsyncTask 已弃用。在 Java 中使用并发或在 Kotlin 中使用协程。您可以从 AsyncTask 返回数据。 ***.com/questions/6053602/… 【参考方案1】:只需将 AsyncTask 设为 Activity 中的嵌套类即可。然后你可以从onPostExecute()
调用属于你的Activity的方法来传递ID值。
免责声明:AsyncTask 很糟糕,您应该使用其他东西。
免责声明 2:如果您关注 MVVM,则 ViewModel 应该处理 ID 而不是 Activity。
【讨论】:
那么问题是,在创建一个新对象时,它的 ID 为 0。只有在再次检索它(通过关闭和打开活动)之后,它才会收到它在数据库中的实际 ID。所以问题是,我创建了对象,然后想要更新它,但由于 Room 找不到 ID“0”而失败。这就是为什么我需要将该 ID 分配给我在 Activity 中创建的对象。 AsyncTasks 不好的任何具体原因或者我可以用什么代替? 好吧,看到 Concurrency here 的相对较长的实现,我认为没有必要仅仅为一些数据库写入重写我的逻辑,因为它们不应该有内存泄漏的风险或类似的东西,这似乎是人们害怕使用AsynkTask
的原因【参考方案2】:
好吧,我最终做了什么,看起来效果不错的是:
基本上使用了这个答案的结构:https://***.com/a/12575319/1972372
并在我的ViewModel
中使用MutableLiveData
对象实现AsynTask
回调接口,以便活动在开始时调用一次并一直保持到更新一次:
public class ChallengeViewModel extends AndroidViewModel implements ChallengesRepository.UpdateChallengeInfosAsyncTask.AsyncResponse
private MutableLiveData<Integer> insertedChlgInfoID;
....
....
public void insertChallengeInfos(ChallengeInfos challengeInfos)
mRepository.insertChallengeInfos(challengeInfos, this);
public LiveData<Integer> getInsertedChlgInfoID()
return insertedChlgInfoID;
@Override
public void processFinish(Long result)
insertedChlgInfoID.setValue(Ints.checkedCast(result));
我理解AsyncTask
在某些情况下可能被称为坏的原因,但我认为在我的情况下它确实工作得很好,并且没有任何潜在的内存泄漏或类似风险,因为它只是非常基本的写入操作。重写整个逻辑似乎对我的情况没有任何好处。
【讨论】:
以上是关于Android Room - 使用自动生成获取新插入行的 id - MVVM 版本的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Android Room 从数据库中获取一行? [复制]
在 Android 的 Room 库中重置自动增量 [关闭]
使用 Android Room 从 Junction Table 获取数据