Mostafa
Mostafa

Reputation: 848

Calling Fragment constructor caused an exception. Navigation Architecture Component

I am using navigation architecture component library and my app's starting point is this fragment:

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

Which inherits from an abstract class which is BaseFragment:

abstract class BaseFragment : Fragment() {

}

When I run my app I get:

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

But this does not happen if MainFragment extends Fragment instead of BaseFragment. What is the reason? Does this have something to do with how the Navigation Architecture Component works?

Upvotes: 20

Views: 11213

Answers (5)

M.Ed
M.Ed

Reputation: 1348

If you're getting this error

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

While using Geofencing API in Fragments, it's because you're not meant to initialize GeofencingClient (or perhaps it could be some other variable on your end) before the Fragment gets constructed, so, delay the initialization of GeofencingClient with a lateinit var and then initialize it in onCreateView.

Upvotes: 0

Besong-Anong Ernest
Besong-Anong Ernest

Reputation: 51

I faced similar issues for a while now. In order to fix the issue, do not use a context related resource before context is initialized.

For example, in case you are using getString() method (context related resource) to access a string value, do use it always in the onViewCreated() method of fragment.

This ensures the context is initialized and thus can be access.

Hope this helps!

Upvotes: 3

pokumars
pokumars

Reputation: 161

I had the same error and none of the above answers helped me because it was actually a different mistake I had made.

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

before onCreateView

my runViewModelhad not yet been instantiated since it was lateinit but I was already referring to it. Changing it to this below solved the problem

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

Upvotes: 2

C Sinclair
C Sinclair

Reputation: 186

I had the same issue, but only on older Android versions. It turned out I had to use a direct descendant of Fragment() Couldn't tell you why this was an issue as it ran fine on newer versions, but I had no choice but to refactor... painful but now functional.

Upvotes: 0

Nux
Nux

Reputation: 7098

I had the similar issue because I had val in MyBaseFragment

protected abstract val gpsMsg: String

which I was overiding this way in other Fragment before fragment attached to context.

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

So the underlying error was because context was null and getString uses getResources() which returns requireContext().getResources(). And in the requireContext() source code error will be thrown.

public final Context requireContext() {
    Context context = getContext();
    if (context == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to a context.");
    }
    return context;
}

So the error thrown causes fragment not to be instantiated. So I would advice being careful with context thing when override.

Upvotes: 18

Related Questions