找不到Fragment构造函数

M.A*_*han 15 android android-fragments

我在某些设备上遇到问题,并在崩溃分析中遇到错误.许多用户设备都面临着这个问题,但在我的设备上它运行正常.

无法启动活动ComponentInfo {com.ox.outloks.new/com.ox.outloks.new.activities.MainDrawerActivity}:android.support.v4.app.Fragment $ InstantiationException:无法实例化片段com.alchemative.outfitters.outfitters .fragments.ProductsFragment:找不到Fragment构造函数

错误发生在活动中的行super.onCreate(savedInstanceState);

  @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
Run Code Online (Sandbox Code Playgroud)

这是ProductsFragment构造函数

    @SuppressLint("ValidFragment")
public ProductsFragment(String id) {
    categoryID = id;
}
Run Code Online (Sandbox Code Playgroud)

Ben*_* P. 33

Fragment您创建的所有类都必须具有public,no-arg构造函数.通常,最佳实践是根本不要定义任何构造函数,并依赖Java为您生成默认构造函数.但你也可以这样写:

public ProductsFragment() {
    // doesn't do anything special
}
Run Code Online (Sandbox Code Playgroud)

如果您的片段需要额外的信息,例如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;
}
Run Code Online (Sandbox Code Playgroud)

现在,new ProductsFragment(id)你打电话,而不是打电话ProductsFragment.newInstance(id).并且,在您的片段中,您可以通过调用来访问ID getArguments().getString("id").

通过利用参数bundle(而不是创建一个特殊的构造函数),您的片段将能够被Android框架销毁并重新创建(例如,如果用户旋转他们的手机)并且您的必要信息(id)将持续存在.

  • 我已经这样做了,但仍然出现错误 - 问题:java.lang.RuntimeException:无法启动活动 ComponentInfo{com.blipclap.wallpaper/com.blipclap.wallpaper.HomeActivity}:androidx.fragment.app.Fragment $InstantiationException:无法实例化片段 com.blipclap.wallpaper.Fragment.RecentsFragment:找不到片段构造函数 (10认同)
  • 如果我需要传递对象变量(可能是 FrameLayout)作为额外信息怎么办?因为我没有看到任何方法将其放入 Bundle 实例中。 (4认同)
  • 我有一个在构造函数中没有参数的片段,但面临着确切的问题,可能出了什么问题?我可能应该提到,当进程死亡发生一段时间后,我打开了我的应用程序。 (2认同)

Thr*_*ian 7

截至今天,接受的答案并不完全正确。使用FragmentFactory

您可以创建片段,例如

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

} 
Run Code Online (Sandbox Code Playgroud)

并在 FragmentFactory 的实例化方法中实例化它

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

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

    }
Run Code Online (Sandbox Code Playgroud)

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

supporFragmentManager.fragmentFactory = yourFragmentFactoryInstance
Run Code Online (Sandbox Code Playgroud)


Ale*_*cha 5

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