调用 Fragment 构造函数导致异常。导航架构组件
Calling Fragment constructor caused an exception. Navigation Architecture Component
我正在使用导航架构组件库,我的应用程序的起点是这个片段:
class MainFragment : BaseFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_main, container, false)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
继承自抽象class,即BaseFragment
:
abstract class BaseFragment : Fragment() {
}
当我 运行 我的应用程序时,我得到:
Unable to instantiate fragment io.example.MainFragment: calling Fragment constructor caused an exception
但如果 MainFragment
扩展 Fragment
而不是 BaseFragment
,则不会发生这种情况。是什么原因?这与导航架构组件的工作方式有关吗?
我遇到了类似的问题,因为我在 MyBaseFragment
中有 val
protected abstract val gpsMsg: String
在片段附加到上下文之前,我在其他片段中以这种方式覆盖。
override val gpsMsg: String = getString(R.string.gps_not_enabled)
所以潜在的错误是因为上下文为空并且 getString 使用 getResources()
其中 returns requireContext().getResources()
。并且在requireContext()
源代码中会抛出错误。
public final Context requireContext() {
Context context = getContext();
if (context == null) {
throw new IllegalStateException("Fragment " + this + " not attached to a context.");
}
return context;
}
所以抛出的错误导致fragment没有被实例化。所以我建议在覆盖时要小心上下文。
我遇到了同样的问题,但仅限于较旧的 Android 版本。结果我不得不使用 Fragment()
的直接后代 无法告诉你为什么这是一个问题,因为它 运行 在较新的版本上很好,但我别无选择,只能重构......痛苦但现在可以使用了。
我遇到了同样的错误,none 上面的答案对我有帮助,因为这实际上是我犯的另一个错误。
class RunFragment : Fragment() {
private lateinit var runViewModel: RunViewModel
var calories= String.format("%.2f",runViewModel.calories)
var distanceTravelled= String.format("%.2f",runViewModel.distanceTravelled)
var stepsRun= String.format("%.2f",runViewModel.stepsRun)
}
onCreateView 之前
我的 runViewModel 尚未实例化,因为它是 lateinit,但我已经在引用它了。改成下面这个解决了问题
private lateinit var runViewModel: RunViewModel
var calories= ""
var distanceTravelled= ""
var stepsRun= ""
override fun onCreateView(.......): View? {
calories= String.format("%.2f",runViewModel.calories)
distanceTravelled= String.format("%.2f",runViewModel.distanceTravelled)
stepsRun= String.format("%.2f",runViewModel.stepsRun)
}
我有一段时间遇到过类似的问题。为了解决这个问题,在初始化上下文之前不要使用上下文相关的资源。
例如,如果您使用 getString()
方法(上下文相关资源)访问字符串值,请始终在片段的 onViewCreated()
方法中使用它。
这确保上下文已初始化,因此可以访问。
希望对您有所帮助!
如果您遇到此错误
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment calling Fragment constructor caused an exception
在 Fragment 中使用 Geofencing API 时,这是因为您不打算在构建 Fragment 之前初始化 GeofencingClient(或者它可能是您端的其他变量),因此,延迟初始化带有 lateinit var
的 GeofencingClient,然后在 onCreateView 中对其进行初始化。
我正在使用导航架构组件库,我的应用程序的起点是这个片段:
class MainFragment : BaseFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_main, container, false)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
继承自抽象class,即BaseFragment
:
abstract class BaseFragment : Fragment() {
}
当我 运行 我的应用程序时,我得到:
Unable to instantiate fragment io.example.MainFragment: calling Fragment constructor caused an exception
但如果 MainFragment
扩展 Fragment
而不是 BaseFragment
,则不会发生这种情况。是什么原因?这与导航架构组件的工作方式有关吗?
我遇到了类似的问题,因为我在 MyBaseFragment
中有 valprotected abstract val gpsMsg: String
在片段附加到上下文之前,我在其他片段中以这种方式覆盖。
override val gpsMsg: String = getString(R.string.gps_not_enabled)
所以潜在的错误是因为上下文为空并且 getString 使用 getResources()
其中 returns requireContext().getResources()
。并且在requireContext()
源代码中会抛出错误。
public final Context requireContext() {
Context context = getContext();
if (context == null) {
throw new IllegalStateException("Fragment " + this + " not attached to a context.");
}
return context;
}
所以抛出的错误导致fragment没有被实例化。所以我建议在覆盖时要小心上下文。
我遇到了同样的问题,但仅限于较旧的 Android 版本。结果我不得不使用 Fragment()
的直接后代 无法告诉你为什么这是一个问题,因为它 运行 在较新的版本上很好,但我别无选择,只能重构......痛苦但现在可以使用了。
我遇到了同样的错误,none 上面的答案对我有帮助,因为这实际上是我犯的另一个错误。
class RunFragment : Fragment() {
private lateinit var runViewModel: RunViewModel
var calories= String.format("%.2f",runViewModel.calories)
var distanceTravelled= String.format("%.2f",runViewModel.distanceTravelled)
var stepsRun= String.format("%.2f",runViewModel.stepsRun)
}
onCreateView 之前
我的 runViewModel 尚未实例化,因为它是 lateinit,但我已经在引用它了。改成下面这个解决了问题
private lateinit var runViewModel: RunViewModel
var calories= ""
var distanceTravelled= ""
var stepsRun= ""
override fun onCreateView(.......): View? {
calories= String.format("%.2f",runViewModel.calories)
distanceTravelled= String.format("%.2f",runViewModel.distanceTravelled)
stepsRun= String.format("%.2f",runViewModel.stepsRun)
}
我有一段时间遇到过类似的问题。为了解决这个问题,在初始化上下文之前不要使用上下文相关的资源。
例如,如果您使用 getString()
方法(上下文相关资源)访问字符串值,请始终在片段的 onViewCreated()
方法中使用它。
这确保上下文已初始化,因此可以访问。
希望对您有所帮助!
如果您遇到此错误
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment calling Fragment constructor caused an exception
在 Fragment 中使用 Geofencing API 时,这是因为您不打算在构建 Fragment 之前初始化 GeofencingClient(或者它可能是您端的其他变量),因此,延迟初始化带有 lateinit var
的 GeofencingClient,然后在 onCreateView 中对其进行初始化。