【问题标题】:Calling Fragment constructor caused an exception. Navigation Architecture Component调用 Fragment 构造函数导致异常。导航架构组件
【发布时间】:2019-01-05 09:21:34
【问题描述】:

我正在使用导航架构组件库,我的应用的起点是这个片段:

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,则不会发生这种情况。是什么原因?这是否与导航架构组件的工作方式有关?

【问题讨论】:

  • 在这里遇到类似的问题。找到解决方案了吗?

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


【解决方案1】:

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

中有 val
protected abstract val gpsMsg: String

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

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

所以潜在的错误是因为上下文为空,而 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;
}

所以抛出的错误导致片段不被实例化。所以我建议在覆盖时要小心上下文。

【讨论】:

  • 谢谢,这很有帮助。添加lazy { getString(R.string.label_aab) } 后,它得到了修复。
【解决方案2】:

我有一段时间遇到过类似的问题。为了解决这个问题,在初始化上下文之前不要使用上下文相关的资源。

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

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

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    我有同样的错误,以上答案都没有帮助我,因为这实际上是我犯的另一个错误。

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

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题,但仅限于较旧的 Android 版本。事实证明我不得不使用Fragment() 的直系后代无法告诉你为什么这是一个问题,因为它在新版本上运行良好,但我别无选择,只能重构......虽然很痛苦,但现在可以正常工作了。

      【讨论】:

        【解决方案5】:

        如果您收到此错误

        androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment calling Fragment constructor caused an exception
        

        在 Fragment 中使用 Geofencing API 时,这是因为您不打算在 Fragment 构建之前初始化 GeofencingClient(或者它可能是您端的其他变量),因此,请使用 @987654322 延迟 GeofencingClient 的初始化@ 然后在 onCreateView 中初始化。

        【讨论】:

          猜你喜欢
          • 2020-09-22
          • 2022-01-24
          • 1970-01-01
          • 2013-03-25
          • 1970-01-01
          • 2018-12-22
          • 1970-01-01
          • 2020-08-06
          • 1970-01-01
          相关资源
          最近更新 更多