【问题标题】:lateinit property homeViewModel has not been initializedlateinit 属性 homeViewModel 尚未初始化
【发布时间】:2019-11-20 21:57:25
【问题描述】:

我有一个问题,我在 fragment_home.xml 中添加了三个 textView(textView、textView2、textView3)和 imageView,当我尝试在 Android Studio 的模拟器上运行应用程序时出现错误lateinit 属性 homeViewModel 尚未初始化。

homeFragment.kt

class homeFragment : Fragment() {

    private lateinit var homeViewModel: homeViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        homeViewModel =
            ViewModelProviders.of(this).get(homeViewModel::class.java)
        val root = inflater.inflate(R.layout.fragment_home, container, false)
        val textView: TextView = root.findViewById(R.id.text_home)
        homeViewModel.text.observe(this, Observer {
            textView.text = it
        })
        return root
    }
}

错误日志

6728-6728/com.radex.mysummercarmanual E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.radex.mysummercarmanual, PID: 6728
    kotlin.UninitializedPropertyAccessException: lateinit property homeViewModel has not been initialized
        at com.radex.mysummercarmanual.ui.home.homeFragment.onCreateView(homeFragment.kt:23)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
        at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2646)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2416)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2372)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2466)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1483)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:620)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
        at android.app.Activity.performStart(Activity.java:7157)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

【问题讨论】:

  • 这里的故事很可能不完整,您需要展示更多代码,您是如何创建片段的?
  • 无关,但你的类名应该大写。

标签: android kotlin textview imageview


【解决方案1】:
  • 尝试在onActivityCreated() 中初始化你的viewModel
  • 不要在onCreateView() 内观察或启动您的 ViewModel
  • 将你的类名从homeFragment重命名为HomeFragment,将homeViewModel重命名为HomeViewModel
  • 您不需要在 Kotlin 中执行 findViewMyId。您可以直接访问查看ID。
  • 变化思路如下

    class HomeFragment : Fragment() {
    
    private lateinit var homeViewModel: HomeViewModel
    
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.fragment_home, container, false)
        return root
    }
    
    
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
        homeViewModel.text.observe(this, Observer {
            text_home.text = it
        })
    }
    }
    

【讨论】:

  • 我是 Android 开发的新手——为什么我们要在 onCreateView() 中保留 ViewModel 启动?谷歌自己的培训应用程序,例如github.com/google-developer-training/…,就在那里。谢谢。
【解决方案2】:

当你初始化homeViewModel 时,你引用了一个未初始化的,所以它给你错误。

ViewModelProviders.of(this).get(***homeViewModel***::class.java)

我认为你的 ViewModel 的类名应该是HomeViewModel,所以试试这个:

private lateinit var homeViewModel: HomeViewModel

...

homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)

【讨论】:

    【解决方案3】:

    根据您的code,当您在片段内部时,请不要在onCreateView() 内部使用initialize ViewModel,这意味着让视图先创建然后初始化viewModel。
    要初始化 viewModel,您必须重写 onActivityCreated() 方法并在其中初始化 viewModel。您的代码将是这样的:

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState) 
        homeViewModel = ViewModelProviders.of(activity!!)[HomeViewModel::class.java]
        homeViewModel.text.observe(this, Observer {
            text_home.text = it
        })
    }
    

    注意这里我传递了activity!! 而不是this,因为只要调用this,就无法在片段内直接获取活动上下文或getActivity()。你必须手动告诉。所以你的viewModel 实例化将是这样的:

    homeViewModel = ViewModelProviders.of(activity!!)[HomeViewModel::class.java]
    

    或者你可以使用if 块,像这样:

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        if(!::homeViewModel.isInitialized){ 
        homeViewModel = ViewModelProviders.of(activity!!)[HomeViewModel::class.java]
        homeViewModel.text.observe(this, Observer {
            text_home.text = it
        })
     }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-03
      • 1970-01-01
      • 2020-12-31
      • 2021-06-11
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多