Jetpack 在无限循环中使用 viewModel 编写 api 调用

Aqu*_*hka 3 android viewmodel kotlin android-jetpack-compose

我正在尝试使用 jetpack compose 构建一个应用程序,但是当涉及到使用视图模型进行 api 调用时,我遇到了无限循环。该应用程序不断调用 api,我不明白为什么。这是我的视图模型:

class LibraryViewModel() : ViewModel() {

var library: ArrayList<PKIssue> = arrayListOf()
var loadLibrary by mutableStateOf(false)


init {
    getLibrary()
}


fun getLibrary(){
    viewModelScope.launch {
        Press.issues(
            result = object : result<ArrayList<Issue>, Error> {
                override fun succeed(result: ArrayList<Issue>?) {
                    loadLibrary = true
                    if (result != null) {
                        library = result
                    }
                  
                }

                override fun failed(error: Error?) {
                    loadLibrary = false
                }
            })
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,一旦我初始化 viewModel,我就会无限调用我的 api,以下是我尝试声明它的方式:

@SuppressLint("StateFlowValueCalledInComposition")
@Destination
@Composable
fun HomeScreen(
    navigator: DestinationsNavigator,
   libraryViewModel: LibraryViewModel = LibraryViewModel()
) {
Run Code Online (Sandbox Code Playgroud)

或在可组合项内:val libraryViewModel = LibraryViewModel()但我遇到了同样的问题,我错过了什么吗?看起来它等待 api 调用结束将 loadLibrary 设置为 true,但同时它仍然在循环中调用 getLibrary()。感谢您的帮助

ian*_*ake 5

当你使用

libraryViewModel: LibraryViewModel = LibraryViewModel()
Run Code Online (Sandbox Code Playgroud)

LibraryViewModel每次该方法重构时,您都会直接构建一个全新的实例。由于您可能会在返回loadLibrary时读取您的值getLibrary,这会导致该方法的重组,从而导致无限循环(因为重组再次导致创建另一个全新的实例...这会启动负载...这会导致另一次重组) 。

相反,您应该遵循有关将 ViewModel 与 Compose 一起使用的文档

  1. 将依赖项添加androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1到您的build.gradle文件中

  2. 使用该viewModel()方法实例化您的 ViewModel。

fun HomeScreen(
    navigator: DestinationsNavigator,
   libraryViewModel: LibraryViewModel = viewModel()
) {
Run Code Online (Sandbox Code Playgroud)

viewModel()方法实际上导致您的 ViewModel 在重组、导航到不同屏幕以及配置更改时被缓存和存储。由于通过使用该方法,您将只有该 ViewModel 的单个实例,因此不会遇到相同的无限循环。