java - 由于 Fragment 类中没有公共(public)构造函数方法,在 android 中旋转设备后出现异常

标签 java android android-fragments android-activity oncreate

我用一个包含 fragment 的 Activity 编写了一个非常简单的程序。
我将 Fragment 构造函数设为私有(private),并且我使用静态 newInstance() 方法返回 fragment 。
当我旋转手机时,问题就开始了。我收到一个异常(exception),上面写着:

Unable to start activity ComponentInfo{com.example.todeleteimmediatley/com.example.MainActivity}: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.DatesFragment: could not find Fragment constructor


我调试了程序,发现异常出现在 onCreate 方法的第一行(调用 super.onCreate() 时)。
有人可以解释一下为什么 Fragment 必须有构造函数,为什么在 super.onCreate() 阶段会出现异常?

最佳答案

当您旋转设备时,您的 Activity将被销毁并重新创建。其中一部分是销毁和重建任何 Fragment s 您的 Activity 正在托管。
在重新创建步骤期间,Android 框架需要实例化您的 Fragment 的新实例。 .默认情况下,它通过调用 Fragment 的无参数构造函数来实现。这意味着这个构造函数必须 (a) 存在并且 (b) 是 public .
这个 fragment 的重新创建是由 super.onCreate() 触发的。您的 Activity 。
一般建议是创建一个 newInstance()工厂方法(如您所做的那样),但要单独保留默认构造函数(即,不要将其设为 private )。是的,这意味着有人仍然可以直接调用构造函数,这是您不希望的,但如果您不想参与 FragmentFactory,则需要这样做。 .
评论中的其他问题

Does it mean that in onCreate I should check if the container already contain a Fragment before adding and commiting? Because as I understand from you,the onCreate().super will restore the old Fragment.


我的建议是只提交一次 Fragment 事务,即您的 Activity 第一次启动时。通常,这是通过检查 savedInstanceState 来实现的。 Bundle 在提交事务之前为空:
if (savedInstanceState == null) {
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.foo, FooFragment.newInstance(...))
            .commit();
}
因为您的 Fragments 是您的 Activity 实例状态的一部分,所以任何娱乐(任何时候 savedInstanceState 不是 null )都将自动为您处理。

Why it is better In newInstance method to add the information that the Fragment needs to the Bundle and not to store them as a members(attributes) of the Fragment?


一切都回到 Android 框架需要创建一个新的 Fragment 实例的事实。如果您只是在 Fragment 上设置了成员字段,Android 框架将不会意识到这些,并且无法保存或恢复它们。
但是,arguments Bundle 是 Android 所知道的。参数被认为是 Fragment 实例状态的一部分(因此也是包含 Activity 的实例状态的一部分),并且会自动保存和恢复。这就是为什么您只能将某些类型的数据放入 arguments 的原因。 bundle ; Android 只知道如何在这个重新创建过程中“写入”和“读取”某些类型的数据。

关于java - 由于 Fragment 类中没有公共(public)构造函数方法,在 android 中旋转设备后出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64974035/

相关文章:

android - 从 Android 的 URL 获取参数

android - 如何为具有多个 fragment 的 Activity 弹出堆栈?

android - 无法获取 Android View 的资源 ID

JAVA - 存储固定大小的图像blob

java - 使用泛型类型的自定义迭代器

java - 制作一个 "memory dump"的java应用程序?

java - 如何在HDFS中的文件上运行系统命令?

javascript - 如何检测在 Android 运行时使用的是哪个 javascript 引擎(v8 或 JSC)?

android - 具有多行的 EditText,就像记事本一样

android - Fragment 上的 AutoCompleteTextView 没有建议