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
ViewModel 在 onCreateView()
内,简单来说就是让视图先创建再初始化 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
})
}
}
我有一个问题,我添加了三个 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
ViewModel 在 onCreateView()
内,简单来说就是让视图先创建再初始化 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
})
}
}