调用Fragment构造函数导致异常。导航架构组件

时间:2019-01-05 09:21:35

标签: android android-fragments android-architecture-components

我正在使用导航体系结构组件库,我的应用程序的起点是以下片段:

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

哪个继承自BaseFragment抽象类:

abstract class BaseFragment : Fragment() {

}

运行我的应用程序时,我得到:

 Unable to instantiate fragment io.example.MainFragment: calling Fragment constructor caused an exception

但是,如果MainFragment扩展了Fragment而不是BaseFragment,则不会发生这种情况。是什么原因?这与导航体系结构组件的工作方式有关吗?

4 个答案:

答案 0 :(得分:2)

我遇到了类似的问题,因为我在 MyBaseFragment

中有val
protected abstract val gpsMsg: String

在片段附加到上下文之前,我正在其他片段中以这种方式进行覆盖。

override val gpsMsg: String = getString(R.string.gps_not_enabled)

所以潜在的错误是因为context为空,并且getString使用getResources()返回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;
}

因此抛出的错误导致片段无法实例化。因此,我建议您在覆盖时要小心上下文。

答案 1 :(得分:0)

我遇到了同样的问题,但仅适用于旧版Android。事实证明,我不得不使用Fragment()的直接后代,因为在新版本上运行得很好,所以无法告诉您这是一个问题的原因,但是我别无选择,只能重构……痛苦但现在可以正常工作。

答案 2 :(得分:0)

我有相同的错误,以上答案均无济于事,因为这实际上是我犯的错误。

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

答案 3 :(得分:0)

一段时间以来,我遇到了类似的问题。为了解决此问题,请勿在初始化上下文之前使用与上下文相关的资源。

例如,如果您使用getString()方法(与上下文相关的资源)来访问字符串值,请始终在片段的onViewCreated()方法中使用它。

这确保上下文已初始化,因此可以访问。

希望这会有所帮助!