簡體   English   中英

Dagger-Hilt @ViewModelInject sharedViewModel 沒有注入片段

[英]Dagger-Hilt @ViewModelInject sharedViewModel not injecting into fragment

我正在嘗試使用Jetpack 教程在片段和活動之間創建共享注入視圖 model。

共享視圖 model 已成功注入到父 MyActivity 中,但在呈現子項時,應用程序因依賴注入失敗而崩潰。 我在下面提供了造成問題的代碼。

提供Session經理:

@InstallIn(ApplicationComponent::class)
@Module
class AppModule {
    @Provides
    @Singleton
    fun provideSessionManager(
        networkClient: NetworkClient
    ): SessionManager {
        return SessionManager(networkClient)
    }
}

要注入共享視圖 Model:

class SharedViewModel @ViewModelInject constructor(
    private var sessionManager: SessionManager
) : ViewModel() {

    var name = MutableLiveData<String>("Shared View Model")
}

並且由父活動和子片段使用。

class MyActionFragment() : Fragment() {
    private val viewModel: SharedViewModel by viewModels()
    override fun onActivityCreated(savedInstanceState: Bundle?) {
       super.onActivityCreated(savedInstanceState)
       Timber.d("View Model Name 1: ${viewModel.name.value}") // This line crashes
    }
}
class MyActivity : AuthenticatedBaseActivity() {
    private val viewModel: SharedViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Timber.d("View Model Name 2: ${viewModel.name.value}") // This line prints
    }
}

然而,當代碼運行時,請注意活動創建了 ViewModel 並訪問了它的值,但是當片段試圖做同樣的事情時,應用程序崩潰了:

**D/MyActivity: View Model Name 2: Shared View Model**
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.xxx.xxx, PID: 16630
    java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxx.ui.main.SharedViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
        at com.xxx.xxx.ui.main.MyActionFragment.getViewModel(Unknown Source:2)
        at com.xxx.xxx.ui.main.MyActionFragment.onActivityCreated(**MyActionFragment.kt:140**)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2718)

此外,當我刪除注入sessionManager的 Hilt 依賴項時,將毫無問題地創建片段和視圖 model。

跟隨這篇文章沒有運氣。

非常感謝使用共享 model 對 Hilt 視圖 model 依賴項注入的任何幫助!! 謝謝!

您可以在Fragment中使用擴展 function :

class MyFragment: Fragment() {
    private val viewModel: SharedViewModel by activityViewModels()
}

活動中:

class MyActivity : Activity() {
    private val viewModel: SharedViewModel by viewModels()
}

您必須提供所有依賴項,在您的情況下未提供 NetworkClient

@Module
@InstallIn(ApplicationComponent::class)
object AppModule {

    @Singleton
    @Provides
    fun provideSessionManager(
        networkClient: NetworkClient
    ): SessionManager = SessionManager(networkClient)

    @Singleton
    @Provides
    fun provideNetworkClient() = NetworkClient()
}

在 Activity 或 Fragment 中使用 @AndroidEntryPoint

@AndroidEntryPoint
class MyActionFragment() : Fragment()



@AndroidEntryPoint
class MyActivity : AuthenticatedBaseActivity()

在活動和片段之間共享數據。 使用下面的代碼。 Hilt doc 對我也不起作用。

活動中

    private val vm by viewModels<StartVM>()

在片段中

private val vm: StartVM by lazy {
    obtainViewModel(requireActivity(), StartVM::class.java, defaultViewModelProviderFactory)
}

Kotlin 擴展

fun <T : ViewModel> Fragment.obtainViewModel(owner: ViewModelStoreOwner,
    viewModelClass: Class<T>,
    viewmodelFactory: ViewModelProvider.Factory
) =
    ViewModelProvider(owner, viewmodelFactory).get(viewModelClass)

像這樣使用

@Module
@InstallIn(ApplicationComponent::class)
object AppModule {

    @Singleton
    @Provides
    fun provideSessionManager(
        networkClient: NetworkClient
    ): SessionManager = SessionManager(networkClient)

    @Singleton
    @Provides
    fun provideNetworkClient() = NetworkClient()
}

在 Activity 或 Fragment 中,使用@AndroidEntryPoint

@AndroidEntryPoint
class MyActionFragment() : Fragment()


@AndroidEntryPoint
class MyActivity : AuthenticatedBaseActivity()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM