而@yydl给出了一个令人信服的理由,为什么newInstance方法更好:
如果Android决定稍后重新创建Fragment,它会调用
片段的无参数构造函数。重载
构造函数不是解决方案。
仍然可以使用构造函数。要了解原因,首先我们需要了解为什么Android使用上述解决方案。
在使用片段之前,需要一个实例。Android调用YourFragment()(无参数构造函数)来构造一个片段的实例。这里你写的任何重载构造函数都将被忽略,因为Android不知道该使用哪个构造函数。
在一个Activity的生命周期中,fragment会像上面那样被创建,并被Android多次销毁。这意味着如果您将数据放在片段对象本身中,一旦片段被销毁,这些数据就会丢失。
为了解决问题,android要求你使用一个Bundle存储数据(调用setArguments()),然后可以从YourFragment访问。参数包受到Android的保护,因此保证是持久化的。
设置这个bundle的一种方法是使用静态的newInstance方法:
public static YourFragment newInstance (int data) {
YourFragment yf = new YourFragment()
/* See this code gets executed immediately on your object construction */
Bundle args = new Bundle();
args.putInt("data", data);
yf.setArguments(args);
return yf;
}
然而,构造函数:
public YourFragment(int data) {
Bundle args = new Bundle();
args.putInt("data", data);
setArguments(args);
}
可以做与newInstance方法完全相同的事情。
当然,这会失败,这也是Android希望你使用newInstance方法的原因之一:
public YourFragment(int data) {
this.data = data; // Don't do this
}
作为进一步的解释,这里是Android的片段类:
/**
* Supply the construction arguments for this fragment. This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment. The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {
if (mIndex >= 0) {
throw new IllegalStateException("Fragment already active");
}
mArguments = args;
}
注意,Android要求参数只在构造时设置,并保证这些参数将被保留。
编辑:正如@JHH在评论中指出的,如果你提供了一个需要一些参数的自定义构造函数,那么Java不会为你的片段提供一个无参数的默认构造函数。所以这需要你定义一个无参数构造函数,这是你可以用newInstance工厂方法避免的代码。
编辑:Android不再允许对片段使用重载构造函数。您必须使用newInstance方法。