Android - 在 Fragment class 中保存成员字段的值
Android - save value of member field in Fragment class
每次显示 Fragment
时,我都在尝试使用 Fragment
class 中的 boolean
做一些事情。
例子
我的应用启动,打开 FirstFragment
并且 boolean
第一次总是 true
,然后我有一个 if
子句来检查它的值:
if (FirstTime) {
FirstTime = false;
} else {
// Other stuff here, cause it's not true.
}
然后,第一次,当 FirstTime
是 true
时,我会去另一个 Fragment
。当我 return 到 Fragment1
和我的 onCreate()
时,我也这样做。总是true
,好像是提神什么的
然后我认为这可能是 Fragment
的问题,每次我按 Fragment1
时,它都会重新启动或发生其他问题。然后,我在 MainActivity
中添加了 getter 和 setter:
public Boolean getFirstTime() {
return FirstTime;
}
public void setFirstTime(Boolean FirstTime) {
this.FirstTime = FirstTime;
}
从一开始就是这样,然后我将代码从 Fragment1
更改为:
if (((MainActivity) getActivity()).getFirstTime())
((MainActivity) getActivity()).setFirstTime(false);
} else {
// Other stuff here, cause it's not true,
}
然而,它仍然说这是真的。
我做错了什么或者我对 Fragments 有什么误解?
有什么办法吗?
简单的解决方案,将布尔值设置为静态。
这当然不符合编程的良好习惯。
为了更直接地回答您的问题,我假设片段和活动被销毁并创建了新实例,因此布尔值再次设置为 true。因此,通过使变量成为静态变量,它的状态将在 class.
的所有实例中保持不变
您假设只要应用程序存在,Fragment
实例就一直存在。这是一个合理的假设,如果该假设为真,您的方法就可以正常工作。
不幸的是,一个 Fragment
在退到后台时被销毁,并在 returns 到前台时重新创建。这就是它出现 "refresh" 的原因。 Activity
则不同。当 Activity
退到背景中时,它不会立即被销毁。相反,它会在当前任务的后台维护一段时间,如果它 returns 到前台,它就是 相同的 实例。
为了解决这个问题,有四种不同的方法:
- 声明
FirstTime
为 static
。这 应该 有效。我以前用过这个。但是,这只应在极端情况下使用,即绝对有必要保留成员字段的值,并且只有在没有其他方法可用的情况下。使变量 static
导致 classic 内存泄漏。
- 在
Fragment
中保存 FirstTime
的值
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("FirstTime", FirstTime);
}
并检索 onCreate()
中的值:
@Override
public void onCreate (Bundle savedInstanceState){
super.onCreate();
FirstTime = savedInstanceState.getBoolean("FirstTime");
}
在全局常量class中声明FirstTime
而不是将它放在Fragment
:
中
public class GlobalConstants{
public static boolean FirstTime = true;
// other global constants ...
}
并像这样在您的 Fragment
中访问它:
if (GlobalConstants.FirstTime) {
GlobalConstants.FirstTime = false;
} else {
//Other stuff here cause it's not true
}
将FirstTime
的值保存在SharedPreference
:
SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("FirstTime", FirstTime);
editor.commit();
并以这种方式检索它的值:
SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
FirstTime = sp.getBoolean("FirstTime", true);
前三种方法将在应用程序处于活动状态时保持 FirstTime
的值。第四种方法将在应用程序的生命周期之后保留 FirstTime
的值,即当应用程序重新启动时,FirstTime
将是 true
或 false
,具体取决于它的值是什么应用程序退出前的最后设置。
参考文献:
1. Handling the Fragment Lifecycle.
编辑:
要了解如何使用 onSaveInstanceState()
,请参阅以下链接:
1. Saving (and Retrieving) Android Instance State.
2. Once for all, how to correctly save instance state of Fragments.
3. Handling Configuration Changes.
它是令人困惑的,但是一旦你理解它就会对你有用。
每次显示 Fragment
时,我都在尝试使用 Fragment
class 中的 boolean
做一些事情。
例子
我的应用启动,打开 FirstFragment
并且 boolean
第一次总是 true
,然后我有一个 if
子句来检查它的值:
if (FirstTime) {
FirstTime = false;
} else {
// Other stuff here, cause it's not true.
}
然后,第一次,当 FirstTime
是 true
时,我会去另一个 Fragment
。当我 return 到 Fragment1
和我的 onCreate()
时,我也这样做。总是true
,好像是提神什么的
然后我认为这可能是 Fragment
的问题,每次我按 Fragment1
时,它都会重新启动或发生其他问题。然后,我在 MainActivity
中添加了 getter 和 setter:
public Boolean getFirstTime() {
return FirstTime;
}
public void setFirstTime(Boolean FirstTime) {
this.FirstTime = FirstTime;
}
从一开始就是这样,然后我将代码从 Fragment1
更改为:
if (((MainActivity) getActivity()).getFirstTime())
((MainActivity) getActivity()).setFirstTime(false);
} else {
// Other stuff here, cause it's not true,
}
然而,它仍然说这是真的。
我做错了什么或者我对 Fragments 有什么误解?
有什么办法吗?
简单的解决方案,将布尔值设置为静态。
这当然不符合编程的良好习惯。
为了更直接地回答您的问题,我假设片段和活动被销毁并创建了新实例,因此布尔值再次设置为 true。因此,通过使变量成为静态变量,它的状态将在 class.
的所有实例中保持不变您假设只要应用程序存在,Fragment
实例就一直存在。这是一个合理的假设,如果该假设为真,您的方法就可以正常工作。
不幸的是,一个 Fragment
在退到后台时被销毁,并在 returns 到前台时重新创建。这就是它出现 "refresh" 的原因。 Activity
则不同。当 Activity
退到背景中时,它不会立即被销毁。相反,它会在当前任务的后台维护一段时间,如果它 returns 到前台,它就是 相同的 实例。
为了解决这个问题,有四种不同的方法:
- 声明
FirstTime
为static
。这 应该 有效。我以前用过这个。但是,这只应在极端情况下使用,即绝对有必要保留成员字段的值,并且只有在没有其他方法可用的情况下。使变量static
导致 classic 内存泄漏。 - 在
Fragment
中保存FirstTime
的值@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean("FirstTime", FirstTime); }
并检索
onCreate()
中的值:@Override public void onCreate (Bundle savedInstanceState){ super.onCreate(); FirstTime = savedInstanceState.getBoolean("FirstTime"); }
在全局常量class中声明
中FirstTime
而不是将它放在Fragment
:public class GlobalConstants{ public static boolean FirstTime = true; // other global constants ... }
并像这样在您的
Fragment
中访问它:if (GlobalConstants.FirstTime) { GlobalConstants.FirstTime = false; } else { //Other stuff here cause it's not true }
将
FirstTime
的值保存在SharedPreference
:SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putBoolean("FirstTime", FirstTime); editor.commit();
并以这种方式检索它的值:
SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE); FirstTime = sp.getBoolean("FirstTime", true);
前三种方法将在应用程序处于活动状态时保持 FirstTime
的值。第四种方法将在应用程序的生命周期之后保留 FirstTime
的值,即当应用程序重新启动时,FirstTime
将是 true
或 false
,具体取决于它的值是什么应用程序退出前的最后设置。
参考文献:
1. Handling the Fragment Lifecycle.
编辑:
要了解如何使用 onSaveInstanceState()
,请参阅以下链接:
1. Saving (and Retrieving) Android Instance State.
2. Once for all, how to correctly save instance state of Fragments.
3. Handling Configuration Changes.
它是令人困惑的,但是一旦你理解它就会对你有用。