@yydl은 왜 newInstance
메소드가 더 좋은지에 대한 설득력있는 이유를 제공합니다 .
안드로이드가 나중에 프래그먼트를 다시 생성하기로 결정하면 프래그먼트의 인수가없는 생성자를 호출합니다. 따라서 생성자를 오버로드하는 것은 해결책이 아닙니다.
여전히 constructor 을 사용하는 것이 가능합니다 . 이것이 왜 그런지 보려면 먼저 위의 대안이 Android에서 사용되는 이유를 알아야합니다.
프래그먼트를 사용하려면 인스턴스가 필요합니다. 안드로이드는 YourFragment()
( 인수 생성자 없음) 호출 하여 프래그먼트의 인스턴스를 구성합니다. 안드로이드는 사용할 생성자를 알 수 없으므로 오버로드 된 생성자는 무시됩니다.
활동의 수명 동안 프래그먼트는 위와 같이 생성되고 Android에 의해 여러 번 파괴됩니다. 즉, 조각 개체 자체에 데이터를 넣으면 조각이 파괴되면 데이터가 손실됩니다.
이 문제를 해결하기 위해 android는 Bundle
(calling setArguments()
)을 사용하여 데이터를 저장하도록 요청합니다 YourFragment
. 인수 bundle
는 Android에 의해 보호되므로 지속적 입니다.
이 번들을 설정하는 한 가지 방법은 정적 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의 Fragment Class입니다.
/**
* 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는 arg 기본 생성자 가 없는 조각을 제공하지 않습니다 . 따라서 팩토리 메소드로 피할 수있는 코드 인 인수 없음 생성자 를 정의해야합니다 newInstance
.
편집 : 안드로이드는 더 이상 조각에 과부하 생성자를 사용할 수 없습니다. 이 newInstance
방법을 사용해야합니다 .