Could not find Fragment constructor

AndroidAndroid Fragments

Android Problem Overview


I am facing the issue on some devices and getting an error on my crash analytics. A lot of user devices are facing this issue, but on my device it's working fine.

> Unable to start activity ComponentInfo{com.ox.outloks.new/com.ox.outloks.new.activities.MainDrawerActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.alchemative.outfitters.outfitters.fragments.ProductsFragment: could not find Fragment constructor

The error is coming at the line which is in activity super.onCreate(savedInstanceState);

  @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

Here is ProductsFragment constructor

    @SuppressLint("ValidFragment")
public ProductsFragment(String id) {
    categoryID = id;
}

Android Solutions


Solution 1 - Android

All Fragment classes you create must have a public, no-arg constructor. In general, the best practice is to simply never define any constructors at all and rely on Java to generate the default constructor for you. But you could also write something like this:

public ProductsFragment() {
    // doesn't do anything special
}

If your fragment needs extra information, like String id in your posted example, a common pattern is to define a newInstance() static "factory method" that will use the arguments Bundle to give that info to your fragment.

public static ProductsFragment newInstance(String id) {
    Bundle args = new Bundle();
    args.putString("id", id);
    ProductsFragment f = new ProductsFragment();
    f.setArguments(args);
    return f;
}

Now, rather than calling new ProductsFragment(id), you'll call ProductsFragment.newInstance(id). And, inside your fragment, you can access the id by calling getArguments().getString("id").

By leveraging the arguments bundle (instead of creating a special constructor), your fragment will be able to be destroyed and recreated by the Android framework (e.g. if the user rotates their phone) and your necessary info (the id) will persist.

Solution 2 - Android

Accepted answer is not entirely correct as of today. With FragmentFactory

you can create fragment such as

MyFragment(arg1:Any, arg2:Any,...) {

} 

and instantiate it inside FragmentFactory's instantiate method

override fun instantiate(classLoader: ClassLoader, className: String): Fragment {

        return when (className) {
            MyFragment::class.java.name -> MyFragment(arg1, arg2)
            
        }

    }

and set your FragmentFactory as supportFragmentManager's fragment factory before onCreate of Activity, because Android checks out for empty constructor fragment and if you don't provide before onCreate your app will crash as usual behavior.

supporFragmentManager.fragmentFactory = yourFragmentFactoryInstance

Solution 3 - Android

A newer alternative to communicate between an Activity and a Fragment, thus allowing that the Fragment can have an empty constructor would be the use of ViewModels.

Solution 4 - Android

I have just faced this exception. My mistake was calling requireArguments() method before arguments were received by the Fragment

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionM.ArslanKhanView Question on Stackoverflow
Solution 1 - AndroidBen P.View Answer on Stackoverflow
Solution 2 - AndroidThracianView Answer on Stackoverflow
Solution 3 - AndroidAlexander PachaView Answer on Stackoverflow
Solution 4 - AndroidMax SiominView Answer on Stackoverflow