lateinit 属性 homeViewModel 尚未初始化

lateinit property homeViewModel has not been initialized

我有一个问题,我添加了三个 textView(textView、textView2、textView3)和 imageView 到 fragment_home.xml,当我尝试 运行 Android Studio 中模拟器上的应用程序我收到错误 lateinit 属性 homeViewModel has not been initialized.

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)
  • 尝试在 onActivityCreated()
  • 中初始化您的 viewModel
  • 不要在 onCreateView()
  • 中观察或启动您的 ViewModel
  • 将您的 class 名称从 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
        })
    }
    }
    

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

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

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

private lateinit var homeViewModel: HomeViewModel

...

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

根据您的 code,因为您在片段内,所以不要 initialize ViewModelonCreateView() 内,简单来说就是让视图先创建再初始化 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,因为你无法在片段中直接获取 activity 上下文或 getActivity()通过调用 this。你必须手动告诉。所以你的 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
    })
 }
}