Android - 保存Fragment类中成员字段的值

Ski*_*ᴉʞS 2 java android sharedpreferences android-lifecycle android-fragments

每次显示时,我都尝试boolean在类中使用 a 来做一些事情。FragmentFragment

例子

我的应用程序启动,打开 ,FirstFragment并且boolean第一次总是true,然后我有一个if子句检查其值:

if (FirstTime) {
    FirstTime = false;
} else {
    // Other stuff here, cause it's not true.
}
Run Code Online (Sandbox Code Playgroud)

然后,在第一次,什么时候FirstTimetrue我做了一些事情,比如去另一个地方Fragment。当我返回Fragment1并在我的 上时onCreate(),我也会做同样的事情。总是true,看起来很清爽什么的。

然后我认为这可能是 的问题Fragment,每次我按 时Fragment1,它都会重新启动或发生其他情况。然后,我在我的中添加了 getter 和 setter MainActivity

public Boolean getFirstTime() {
    return FirstTime;
}

public void setFirstTime(Boolean FirstTime) {
    this.FirstTime = FirstTime;
}
Run Code Online (Sandbox Code Playgroud)

从一开始,这是真的,然后,我将代码更改Fragment1为:

if (((MainActivity) getActivity()).getFirstTime())
    ((MainActivity) getActivity()).setFirstTime(false);
} else {
    // Other stuff here, cause it's not true,
}
Run Code Online (Sandbox Code Playgroud)

然而,它仍然说这是真的。

我做错了什么或者我对 Fragment 有什么误解?
有什么办法可以做到吗?

Y.S*_*Y.S 5

您假设只要Fragment应用程序处于活动状态,实例就保持存在。这是一个合理的假设,如果该假设成立,您的方法将会很好地工作。

不幸的是,aFragment在退到后台时被销毁,并在返回前台时被重新创建。这就是为什么它看起来“刷新”。但对于 来说则不然Activity。当一个Activity物体退到背景中时,它不会立即被摧毁。相反,它会在当前任务的返回堆栈上维护一段时间,如果它返回到前台,则它是同一个实例

为了解决这个问题,有四种不同的方法:

  • 声明FirstTimestatic. 这应该有效。我以前用过这个。但是,只有在极端情况下才应使用此方法,即绝对有必要保留成员字段的值,并且只有在没有其他方法可用时。创建变量static会导致典型的内存泄漏。
  • FirstTime保存您Fragment使用的值onSaveInstanceState()

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("FirstTime", FirstTime);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    并检索以下值onCreate()

    @Override
    public void onCreate (Bundle savedInstanceState){
        super.onCreate();
        FirstTime = savedInstanceState.getBoolean("FirstTime");
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 在全局常量类中声明FirstTime而不是将其放入Fragment

    public class GlobalConstants{
    
        public static boolean FirstTime = true;
        // other global constants ...
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    并像这样访问它Fragment

    if (GlobalConstants.FirstTime) {
        GlobalConstants.FirstTime = false;
    } else {
        //Other stuff here cause it's not true
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 将 的值保存FirstTime在 a 中SharedPreference

    SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();
    editor.putBoolean("FirstTime", FirstTime);
    editor.commit();
    
    Run Code Online (Sandbox Code Playgroud)

    并以这种方式检索其值:

    SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
    FirstTime = sp.getBoolean("FirstTime", true);
    
    Run Code Online (Sandbox Code Playgroud)

FirstTime前三个方法将在应用程序处于活动状态时保持 的值。FirstTime第四种方法将保留超出应用程序生命周期的值,即当应用程序重新启动时,FirstTime将保留truefalse取决于应用程序退出之前最后设置的值。

参考:

1. 处理片段生命周期

2. 保存键值集

3. 可见性和生命周期

编辑:

要了解如何使用onSaveInstanceState(),请参阅以下链接:

1. 保存(和检索)Android 实例状态

2. 总而言之,如何正确保存 Fragments 的实例状态

3. 处理配置更改

令人困惑,但一旦你理解了它,它就会对你有用。