为什么使用newInstance for DialogFragment而不是构造函数?

Ric*_*ral 13 android constructor android-dialogfragment

综观文件DialogFragment,人们看到的静态newInstance方法来初始化一个新的警告对话框片段.我的问题是,为什么不使用构造函数来这样做,像这样:

public MyAlertDialogFragment(int title) {
    Bundle args = new Bundle();
    args.putInt("title", title);
    setArguments(args);
}
Run Code Online (Sandbox Code Playgroud)

这不完全相同,还是以某种方式不同?什么是最好的方法,为什么

GaR*_*eTa 23

如果您创建一个通过构造函数接收对象的DialogFragment,那么当android 重新创建您的片段时,您将遇到问题.这将是会发生的事情:

  1. 您的代码创建对话框,调用您创建的构造函数并将一些参数作为依赖项传递.
  2. 对话框运行,并使用您通过构造函数传递的依赖项
  3. 用户关闭应用程序
  4. 时间过去了,android杀死了片段以释放内存
  5. 用户再次打开应用程序
  6. android将重新创建对话框,这次使用默认构造函数.没有参数将被传递!
  7. 您的对话框将处于不受欢迎的状态.它可能会尝试使用您希望通过构造函数传递的实例变量,但由于它们不存在,您将获得空指针异常.

为避免这种情况,您不必依赖构造函数来建立依赖关系,而是在Bundles(参数和已保存的实例)中.这可能会迫使你在某些类中实现Parcelable,这很糟糕.

编辑:您可以通过在开发设置中启用"不维护活动"来重现Android杀死应用程序(步骤4).这是轻松测试它的方法.


ant*_*nyt 19

Android依赖于具有公共零参数构造函数的Fragment,以便它可以在不同时间重新创建它(例如配置更改,在以前被Android杀死之后恢复应用程序状态等).

如果你没有这样的构造函数(例如问题中的那个),当你试图实例化一个时,你会看到这个错误:

Fragment$InstantiationException: Unable to instantiate fragment 
make sure class name exists, is public, and has an empty constructor that is public
Run Code Online (Sandbox Code Playgroud)

给予它的参数Fragment.setArguments(Bundle)将为您保存并提供给(重新)创建的任何新实例.使用静态方法创建Fragment只是提供了一种简单的方法来设置所需的参数,同时保持零参数构造函数.

  • 是的,我想这也可行,你可以在自己构建它时使用multi-arg构造函数,然后Android会在重新创建它时使用零arg.如果在multi-arg构造函数中使用了setArguments(..),则会正确保存参数.你真的只需要清楚地了解重新创建片段时会发生什么 - 静态工厂方法样式使我对它更加独特,但这可能是因为我(和许多其他人)使用这种方式.遵循标准约定将使您的代码更容易被其他人理解. (4认同)
  • 如果我添加 2 个构造函数怎么办?两者都是公开的,一个是零参数,另一个是我想要的参数......这也行吗? (2认同)

Gun*_*son 11

如果你用构造函数重载MyAlertDialogFragment(int title),MyAlertDialogFragment()那么如果Fragment需要重新创建并且不传递参数,Android系统仍然可以调用默认构造函数.

  • 你问:"我的问题是,为什么不使用构造函数来执行此操作,如下所示:public MyAlertDialogFragment(int title)".我的回答是,如果你使用这个构造函数,如果Android系统重新创建了Fragment,那么它可能不会被调用,并且你想传递的参数不会被传递.所以不要使用这种方法. (3认同)
  • 这个答案没有意义.拥有一个构造函数是完全有效的; 你只需要提供另一个没有参数的构造函数. (2认同)
  • 如果您旋转设备,我认为这会给您带来问题。它不会调用你的构造函数,它只会调用默认的构造函数。因此,您打算通过重载构造函数设置的任何内容都不会执行。 (2认同)
  • 如果你不在构造函数中调用setArguments(Bundle),这个答案是有意义的,这不是这里的情况. (2认同)