android-fragments 找不到片段构造函数

ruyhziif  于 2022-11-13  发布在  Android
关注(0)|答案(6)|浏览(195)

我在一些设备上遇到了这个问题,并且在我的崩溃分析中出现了错误。很多用户设备都遇到了这个问题,但是在我的设备上它工作正常。
无法启动活动组件信息{com.ox.outloks.new/com.ox.outloks.new.activities.MainDrawerActivity}:示例化异常:无法示例化片段com.alchemative.outfitters.outfitters.fragments.产品片段:找不到片段构造函数
活动super.onCreate(savedInstanceState)中的行出现错误;

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

下面是ProductsFragment构造函数

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

kxxlusnw1#

你创建的所有Fragment都必须有一个公共的、无参数的构造函数。一般来说,最好的做法是根本不定义任何构造函数,而依靠Java为你生成默认的构造函数。但是你也可以这样写:

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

如果你的片段需要额外的信息,比如你发布的例子中的String id,一个常见的模式是定义一个newInstance()静态“工厂方法”,该方法将使用参数Bundle为你的片段给予该信息。

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

现在,我们将调用ProductsFragment.newInstance(id),而不是调用new ProductsFragment(id),并且,在片段中,可以通过调用getArguments().getString("id")来访问id。
通过利用arguments bundle(而不是创建一个特殊的构造函数),您的片段将能够被Android框架销毁并重新创建(例如,如果用户旋转他们的手机),并且您的必要信息(id)将持续存在。

zvokhttg

zvokhttg2#

截至今天,已接受的答案不完全正确。使用FragmentFactory
您可以创建片段,例如

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

}

并在FragmentFactory示例化方法中示例化它

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

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

    }

并在Activity的onCreate之前将FragmentFactory设置为supportFragmentManager的片段工厂,因为Android会检查空的构造函数片段,如果您在onCreate之前不提供,您的应用将像通常的行为一样崩溃。

supporFragmentManager.fragmentFactory = yourFragmentFactoryInstance
vnjpjtjt

vnjpjtjt3#

在Activity和Fragment之间进行通信的一个较新的替代方法是使用ViewModels,从而允许Fragment可以有一个空的构造函数。

qvk1mo1f

qvk1mo1f4#

我刚刚遇到了这个异常。我的错误是在Fragment接收到参数之前调用了requireArguments()方法

zxlwwiss

zxlwwiss5#

问题来自下面的fragment类的方法,它基本上显示了我们应该如何初始化我们的fragment类。首先看下面的方法:-

public static Fragment instantiate(@NonNull Context context, @NonNull String fname,
        @Nullable Bundle args) {
    try {
        Class<? extends Fragment> clazz = FragmentFactory.loadFragmentClass(
                context.getClassLoader(), fname);
        Fragment f = clazz.getConstructor().newInstance();
        if (args != null) {
            args.setClassLoader(f.getClass().getClassLoader());
            f.setArguments(args);
        }
        return f;
    } catch (java.lang.InstantiationException e) {
        throw new InstantiationException("Unable to instantiate fragment " + fname
                + ": make sure class name exists, is public, and has an"
                + " empty constructor that is public", e);
    } catch (IllegalAccessException e) {
        throw new InstantiationException("Unable to instantiate fragment " + fname
                + ": make sure class name exists, is public, and has an"
                + " empty constructor that is public", e);
    } catch (NoSuchMethodException e) {
        throw new InstantiationException("Unable to instantiate fragment " + fname
                + ": could not find Fragment constructor", e);
    } catch (InvocationTargetException e) {
        throw new InstantiationException("Unable to instantiate fragment " + fname
                + ": calling Fragment constructor caused an exception", e);
    }
}

因此,如果您将看到问题在于catch(NoSuchMethodException e)代码块,该代码块在这种情况下触发,因为它无法检测来自行Fragment f = clazz.getConstructor().newInstance()的片段的构造函数;.如果您将看到函数getConstructor(),您将观察到这将负责生成此异常,因为它抛出此NoSuchMethodException,并且在Fragment instantiate函数内部捕获了相同的异常。此外,如果您进一步移动上述函数,还将给出将参数发送到片段参数的推荐方法。因此,现在我们都清楚该怎么做了。
1.为了将数据发送到片段中,我们应该创建接收方片段的示例/静态函数,并将所有需要的参数放入其中。
1.然后使用片段参数将数据放入示例函数内的接收器片段中。
1.最后,只需将这些参数输入到onCreate/onCreateView中。

**注意:此Fragment类在API级别28中已弃用。**使用Jetpack Fragment Library Fragment可在所有设备上实现一致的行为并访问生命周期。

jaxagkaj

jaxagkaj6#

如果在片段的onCreate()之前调用requireContext()方法,也可能发生这种情况。

相关问题