调用 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 中对其进行初始化。