【发布时间】:2020-10-10 02:11:54
【问题描述】:
我目前的用法是将 5 个特定按钮的信息存储到数据库(房间)中,以便在重新启动时将其保留。我当前的使用不依赖于数据的更改,因为唯一更改数据的是长按按钮的用户(然后我更新数据库)。因此我不需要 LiveData 变量,这让我很难初始化我的 ViewModel。
本质上,由于 LiveData 对象仅在更改时更新,因此我的数据永远不会被初始化。 因此,应用程序在启动时总是会导致一个空指针。
我将在下面分享我的设置要点。我希望有一些方法可以让我不必观察任何 LiveData 对象,并且可以在实例化模型时获取数据。
实体:
@Entity(tableName = "myEntity")
public class MyEntity {
@PrimaryKey
public int buttonID;
// other fields...
}
道:
@Dao
interface MyDAO {
@Query("Select * from myDB")
LiveData<List<MyEntity>> getEntityList();
// I think this needs to change to just List<MyEntity>?
// also insert and update here...
}
存储库:
class MyRepository {
private MyDAO myDAO;
private LiveData<List<MyEntity>> allEntities;
MyRepository(Application application) {
MyDatabase db = MyDatabase.getInstance(application);
myDAO = db.myDAO();
allEntities = myDAO.getAllEntities();
}
LiveData<List<MyEntity>> getAllEntities() { return allEntities; }
// Update entity...
}
视图模型:
public class ViewModel extends AndroidViewModel {
private MyRepository repository;
private List<MyEntity> tempList;
private HashMap<MyEntity> allEntities;
public ViewModel (Application application) {
super(application);
repository = new MyRepository(application);
Observer<List<MyEntity>> observer = data -> tempList = data;
ObserveOnce(repository.getAllEntities(), observer); // ObserveOnce implementation found in this answer: https://stackoverflow.com/a/59845763/10013384
allEntities = new HashMap<>();
for (int i = 0; i < tempList.size(); i++) { // Nullpointer here, as tempList doesn't have any items yet.
allEntities.put(tempList.get(i).buttonID, templist.get(i));
}
}
// getter and update methods...
}
活动:
// ...
protected void onCreate(Bundle savedInstanceState) {
// ...
viewModel = new ViewModelProvider(this).get(ViewModel.class);
// Initialize UI views with data from ViewModel
}
然后在各自的监听器中:
@Override
public boolean onLongClick(View v) {
int index = (Integer) v.getTag();
data.get(index).foo = fooNewUIData;
ButtonArray[index].setText(fooNewUIData);
ViewModel.update(data.get(index)); // if updated, update the ViewModel and the database
}
【问题讨论】:
-
您的存储库实现看起来很奇怪。如果
getAllEntities()应该从 Room 返回数据,您需要在某处涉及您的 DAO。现在,您正在返回一个未初始化的LiveData,这不太可能正常工作。此外,通常,视图模型使用数据将LiveData暴露给活动/片段,而不是尝试使用LiveData本身。 -
哎呀,对不起,我会把我的 DAO 放在这里以供参考
-
“我会把我的 DAO 放在这里以供参考”——是的,但你没有使用它。
-
用构造函数更新
-
我什至没注意你的代码细节; 但这个问题本身就很好! 你可以在没有 LiveData 的情况下使用 Room 吗?即使对 SQL 了解很多,我也感觉自己像个使用 Room 的 n00b;有时,您只能通过 LiveData
, due to the limitationLiveData 与数据库进行交互,这意味着 -> 您只能从LifecycleOwners 观察它 -> AFAIK 只有活动才是。 PD:我仍然拒绝学习 Kotlin,我继续使用 Java:P
标签: java android android-room viewmodel android-livedata