lateinit property homeViewModel has not been initialized

陌路散爱 提交于 2020-01-25 08:34:07

问题


I have a problem, I added three textView (textView, textView2, textView3) and imageView to fragment_home.xml and when I try to run the application on the emulator in Android Studio I get the error lateinit property 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
    }
}

error log

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)

回答1:


  • Try initialise your viewModel inside onActivityCreated()
  • Don't observe or initiate you ViewModel inside onCreateView()
  • Rename your class name from homeFragment to HomeFragment and homeViewModel to HomeViewModel
  • You don't need to do findViewMyId in Kotlin. you can access view directly ID.
  • The change Idea is bellow

    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
        })
    }
    }
    



回答2:


When you initialize homeViewModel, you reference an uninitialized one so it gives you the error.

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

I think the class name of your ViewModel should be HomeViewModel, so try this one:

private lateinit var homeViewModel: HomeViewModel

...

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



回答3:


According to your code, as you're inside fragment do not initialize ViewModel inside onCreateView(), simply means let the view create first then initilalize viewModel.
To initialize viewModel you have to override onActivityCreated() method and initialize viewModel inside it. Your code will be like this:

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

And notice here i pass activity!! rather than this, cause you just can't get the activity context or getActivity() directly whenever you're inside the fragment just by calling this. You have to tell manually. So your viewModel instantiation will be like this:

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

Or You could use if block, like this:

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
    })
 }
}


来源:https://stackoverflow.com/questions/58964019/lateinit-property-homeviewmodel-has-not-been-initialized

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!