Android Navigation Error: java.lang.IllegalArgumentException: navigation destination com.example--- is unknown to this NavController
Android Navigation Error: java.lang.IllegalArgumentException: navigation destination com.example--- is unknown to this NavController
-
android
-
android-fragments
-
android-studio
-
android-architecture-components
-
android-architecture-navigation
我收到一个错误:java.lang.IllegalArgumentException,只有当我从 LoginFragment
导航到 RegisterFragment
然后按返回按钮转到上一个片段时才会发生错误(LoginFragment
) 并输入电子邮件和密码,然后按登录按钮。当我注释行 view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToHomeContainerFragment())
时,错误没有发生,但我必须导航到 HomeFragment
。如何解决?
注意: 当您不导航到 RegisterFragment
时,不会发生错误
登录片段:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
{
val binding: FragmentLoginBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false)
val login = binding.loginBtn
val emailField = binding.inputEmail
val passwordField = binding.inputPassword
val signUp = binding.loginSignup
binding.viewModel = viewModel
binding.lifecycleOwner = this
signUp.setOnClickListener {
view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToRegisterFragment())
}
login.setOnClickListener {
val email = emailField.text.toString().trim()
val password = passwordField.text.toString().trim()
if(email.isEmpty())
{
.................
}
if(!Patterns.EMAIL_ADDRESS.matcher(email).matches())
{
.................
}
viewModel.userLogin(email,password)
}
viewModel.loginAuthData.observe(this, Observer { userAuthData ->
if(userAuthData.checkAuth != null)
{
if(userAuthData.checkAuth!!)
{
Snackbar.make(activity!!.findViewById(android.R.id.content), "Auth Pass", Snackbar.LENGTH_SHORT).show()
//The error doesn't occur if i comment this line >>
view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToHomeContainerFragment())
}
else
{
Snackbar.make(activity!!.findViewById(android.R.id.content), "Auth Fail", Snackbar.LENGTH_SHORT).show()
}
}
})
return binding.root
}
错误:
Process: com.example.---, PID: 24721
java.lang.IllegalArgumentException: navigation destination com.example.---:id/action_loginFragment_to_homeContainerFragment is unknown to this NavController
at androidx.navigation.NavController.navigate(NavController.java:789)
at androidx.navigation.NavController.navigate(NavController.java:730)
at androidx.navigation.NavController.navigate(NavController.java:716)
at androidx.navigation.NavController.navigate(NavController.java:907)
at com.example.---.ui.login.LoginFragment$onCreateView.onChanged(LoginFragment.kt:71)
at com.example.---.ui.login.LoginFragment$onCreateView.onChanged(LoginFragment.kt:20)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at com.example.---.viewModel.LoginViewModel.authCallBack(LoginViewModel.kt:37)
at com.example.---.viewModel.LoginViewModel.access$authCallBack(LoginViewModel.kt:12)
at com.example.---.viewModel.LoginViewModel$firebaseUserAuth.invoke(LoginViewModel.kt:15)
at com.example.---.viewModel.LoginViewModel$firebaseUserAuth.invoke(LoginViewModel.kt:12)
at com.example.---.data.FirebaseUserAuth$login.onComplete(FirebaseUserAuth.kt:27)
at com.google.android.gms.tasks.zzj.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
尝试获取包含 Activity
Activity.findNavController(IdOfView)
的 NavController 而不是 view!!.findNavController()
有关导航的更多信息:
https://developer.android.com/reference/kotlin/androidx/navigation/package-summary#findnavcontroller
您正在 onCreateView()
中使用 viewModel.loginAuthData.observe(this, Observer {})
,即使用 Fragment
(通过 this
)作为您观察的 LifecycleOwner。这总是错误的——当从 onCreateView()
:
观察时,你应该改用 viewLifecycleOwner
viewModel.loginAuthData.observe(viewLifecycleOwner, Observer {
...
})
LiveData 的工作原理是它会继续保持注册状态,直到给定的 LifecycleOwner
被销毁。当你传递 this
时,它会等待 Fragment 本身被销毁。但是,碎片在返回堆栈时 不会 被销毁(只有它们的视图以及它们的 viewLifecycleOwner
被销毁)。这意味着 original LiveData 永远不会注销其观察者。
这意味着当 onCreateView()
第二次发生时(即,您点击后退按钮并重新创建视图),将创建并注册 second 观察者.您现在 两个 个观察者同时 运行ning。由于他们都 运行,第一个成功 运行 并调用 navigate()
。当第二个 运行s 时,NavController 已经移动到下一个目的地,因此不再找到在前一个目的地注册的任何操作,给你一个 IllegalArgumentException
.
通过使用viewLifecycleOwner
,当片段的视图被销毁时,原始的 LiveData 被正确地销毁。这意味着当你回击并再次调用 onCreateView
时,一次只有一个观察者处于活动状态,你不会 运行 进入这个问题。
android
android-fragments
android-studio
android-architecture-components
android-architecture-navigation
我收到一个错误:java.lang.IllegalArgumentException,只有当我从 LoginFragment
导航到 RegisterFragment
然后按返回按钮转到上一个片段时才会发生错误(LoginFragment
) 并输入电子邮件和密码,然后按登录按钮。当我注释行 view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToHomeContainerFragment())
时,错误没有发生,但我必须导航到 HomeFragment
。如何解决?
注意: 当您不导航到 RegisterFragment
登录片段:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
{
val binding: FragmentLoginBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false)
val login = binding.loginBtn
val emailField = binding.inputEmail
val passwordField = binding.inputPassword
val signUp = binding.loginSignup
binding.viewModel = viewModel
binding.lifecycleOwner = this
signUp.setOnClickListener {
view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToRegisterFragment())
}
login.setOnClickListener {
val email = emailField.text.toString().trim()
val password = passwordField.text.toString().trim()
if(email.isEmpty())
{
.................
}
if(!Patterns.EMAIL_ADDRESS.matcher(email).matches())
{
.................
}
viewModel.userLogin(email,password)
}
viewModel.loginAuthData.observe(this, Observer { userAuthData ->
if(userAuthData.checkAuth != null)
{
if(userAuthData.checkAuth!!)
{
Snackbar.make(activity!!.findViewById(android.R.id.content), "Auth Pass", Snackbar.LENGTH_SHORT).show()
//The error doesn't occur if i comment this line >>
view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToHomeContainerFragment())
}
else
{
Snackbar.make(activity!!.findViewById(android.R.id.content), "Auth Fail", Snackbar.LENGTH_SHORT).show()
}
}
})
return binding.root
}
错误:
Process: com.example.---, PID: 24721
java.lang.IllegalArgumentException: navigation destination com.example.---:id/action_loginFragment_to_homeContainerFragment is unknown to this NavController
at androidx.navigation.NavController.navigate(NavController.java:789)
at androidx.navigation.NavController.navigate(NavController.java:730)
at androidx.navigation.NavController.navigate(NavController.java:716)
at androidx.navigation.NavController.navigate(NavController.java:907)
at com.example.---.ui.login.LoginFragment$onCreateView.onChanged(LoginFragment.kt:71)
at com.example.---.ui.login.LoginFragment$onCreateView.onChanged(LoginFragment.kt:20)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at com.example.---.viewModel.LoginViewModel.authCallBack(LoginViewModel.kt:37)
at com.example.---.viewModel.LoginViewModel.access$authCallBack(LoginViewModel.kt:12)
at com.example.---.viewModel.LoginViewModel$firebaseUserAuth.invoke(LoginViewModel.kt:15)
at com.example.---.viewModel.LoginViewModel$firebaseUserAuth.invoke(LoginViewModel.kt:12)
at com.example.---.data.FirebaseUserAuth$login.onComplete(FirebaseUserAuth.kt:27)
at com.google.android.gms.tasks.zzj.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
尝试获取包含 Activity
Activity.findNavController(IdOfView)
的 NavController 而不是 view!!.findNavController()
有关导航的更多信息: https://developer.android.com/reference/kotlin/androidx/navigation/package-summary#findnavcontroller
您正在 onCreateView()
中使用 viewModel.loginAuthData.observe(this, Observer {})
,即使用 Fragment
(通过 this
)作为您观察的 LifecycleOwner。这总是错误的——当从 onCreateView()
:
viewLifecycleOwner
viewModel.loginAuthData.observe(viewLifecycleOwner, Observer {
...
})
LiveData 的工作原理是它会继续保持注册状态,直到给定的 LifecycleOwner
被销毁。当你传递 this
时,它会等待 Fragment 本身被销毁。但是,碎片在返回堆栈时 不会 被销毁(只有它们的视图以及它们的 viewLifecycleOwner
被销毁)。这意味着 original LiveData 永远不会注销其观察者。
这意味着当 onCreateView()
第二次发生时(即,您点击后退按钮并重新创建视图),将创建并注册 second 观察者.您现在 两个 个观察者同时 运行ning。由于他们都 运行,第一个成功 运行 并调用 navigate()
。当第二个 运行s 时,NavController 已经移动到下一个目的地,因此不再找到在前一个目的地注册的任何操作,给你一个 IllegalArgumentException
.
通过使用viewLifecycleOwner
,当片段的视图被销毁时,原始的 LiveData 被正确地销毁。这意味着当你回击并再次调用 onCreateView
时,一次只有一个观察者处于活动状态,你不会 运行 进入这个问题。