Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 您可以使用room而不使用LiveData对象吗?_Java_Android_Android Room_Viewmodel_Android Livedata - Fatal编程技术网

Java 您可以使用room而不使用LiveData对象吗?

Java 您可以使用room而不使用LiveData对象吗?,java,android,android-room,viewmodel,android-livedata,Java,Android,Android Room,Viewmodel,Android Livedata,我目前的用法是将5个特定按钮的信息存储到数据库(文件室)中,以便在重新启动时将其持久化。我当前的使用不依赖于数据的更改,因为唯一更改数据的是用户长按按钮(然后我更新数据库)。因此,我不需要LiveData变量,这使得我很难初始化ViewModel 本质上,由于LiveData对象只在更改时更新,因此我的数据永远不会初始化。 因此,应用程序在启动时总是会导致空指针 我将在下面分享到目前为止我的设置要点。我希望有某种方法可以使这项工作在我不必观察任何LiveData对象的情况下进行,并且我可以在实例

我目前的用法是将5个特定按钮的信息存储到数据库(文件室)中,以便在重新启动时将其持久化。我当前的使用不依赖于数据的更改,因为唯一更改数据的是用户长按按钮(然后我更新数据库)。因此,我不需要LiveData变量,这使得我很难初始化ViewModel

本质上,由于LiveData对象只在更改时更新,因此我的数据永远不会初始化。 因此,应用程序在启动时总是会导致空指针

我将在下面分享到目前为止我的设置要点。我希望有某种方法可以使这项工作在我不必观察任何LiveData对象的情况下进行,并且我可以在实例化模型时获取数据

实体:

@实体(tableName=“myEntity”)
公共类MyEntity{
@主键
公共int按钮;
//其他领域。。。
}
道:

@Dao
接口MyDAO{
@查询(“从myDB中选择*)
LiveData getEntityList();
//我认为这需要改为仅仅列出?
//也在这里插入和更新。。。
}
存储库:

classmyrepository{
私人密道密道;
私有LiveData Allenties;
MyRepository(应用程序){
MyDatabase db=MyDatabase.getInstance(应用程序);
myDAO=db.myDAO();
allenties=myDAO.getAllenties();
}
LiveData GetAllenties(){return Allenties;}
//更新实体。。。
}
视图模型:

public类ViewModel扩展了AndroidViewModel{
私有MyRepository存储库;
私人名单圣殿骑士;
私有HashMap allenties;
公共视图模型(应用程序){
超级(应用);
repository=新的MyRepository(应用程序);
观察者=数据->模板列表=数据;
ObserveOnce(repository.getAllenties(),observer);//在这个答案中找到了ObserveOnce实现:https://stackoverflow.com/a/59845763/10013384
allenties=newhashmap();
对于(inti=0;i
活动:

/。。。
创建时受保护的void(Bundle savedInstanceState){
// ...
viewModel=newviewmodelprovider(this.get)(viewModel.class);
//使用ViewModel中的数据初始化UI视图
}
然后在相应的侦听器中:

@覆盖
仅长按公共布尔值(视图v){
int index=(整数)v.getTag();
data.get(index.foo=fooNewUIData;
ButtonArray[index].setText(FoonNewUIData);
ViewModel.update(data.get(index));//如果已更新,则更新ViewModel和数据库
}

是的,当然可以。只需将
DAO
中特定函数的返回类型从
LiveData
更改为
MyDataClass


有关
Room

的更多教程,请参见本教程。当然,您可以返回普通对象类<仅当您希望观察这些行的更改时,才需要使用code>LiveData

您还可以使用to kotlin flows来监听更改,而不使用
LiveData

没有LiveData:

List<MyEntity> getAllEntities();
列出getAllenties();
对于Kotlin流:

fun getAllEntities(): Flow<List<MyEntity>>
fun getAllenties():流
希望这有帮助

由于LiveData对象仅在更改时更新,因此我的数据从未初始化


那不是你的问题。您的问题是,您认为
ObserveOnce()
是一个阻塞调用,当它返回时,结果将立即准备好。实际上,Room中的
LiveData
确实可以在后台线程上工作。您需要对您的
观察者中的数据可用时作出反应,而不是假设它将在下一次声明中可用。

好的,感谢所有提供的答案和反馈,我非常感谢

最后,我同意@commonware的观点,处理这个问题最简单的方法可能是不要让
ViewModel
使用
LiveData
。我选择在我的活动中设置一个
观察者
,并在将数据保存到我的活动类时将其转换为我想要的格式(
ArrayList

我最初关心的问题是数据没有按照我的喜好进行排序,否则可以通过简单的排序来解决:

Collections.sort(this.data,(o1,o2)->Integer.compare(o1.buttonID,o2.buttonID));
至于异步问题,我只是退回到允许观察者的回调在获取数据时更新数据(并相应地更新UI)。如果这种情况涉及更多的数据,那么在应用程序加载数据时,我可能需要一些启动屏幕。但幸运的是,我还不需要做这些

活动:

//onCreate(){
ViewModel=newviewmodelprovider(this.get)(ViewModel.class);
观察者=this::setData;
observeOnce(ViewModel.getAllenties(),observer);
如果(data.size()>0){
//初始化UI视图
}
// }
//...
公共void setData(列出实体){
this.data=实体
Collections.sort(this.data,(o1,o2)->Integer.compare(o1.buttonID,o2.buttonID));
//如果需要,还可以更新UI
}

剩下的唯一一件事就是解决我的数据库在重新启动时无法持久化的问题,但这超出了这个问题的范围。

您的存储库实现似乎很奇怪。如果
getAllenties()
应该从文件室返回数据,您需要将DAO包含在某个地方。现在,您正在返回一个未初始化的
LiveData
,这不太可能正常工作。此外,通常,viewmodel使用数据而不是attem向活动/片段公开
LiveData