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.
}

然后,第一次,当 FirstTimetrue 时,我会去另一个 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 到前台,它就是 相同的 实例。

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

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

    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 将是 truefalse,具体取决于它的值是什么应用程序退出前的最后设置。

参考文献:

1. Handling the Fragment Lifecycle.

2. Saving Key-Value Sets.

3. Visibility and Lifetime.

编辑:

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

1. Saving (and Retrieving) Android Instance State.

2. Once for all, how to correctly save instance state of Fragments.

3. Handling Configuration Changes.

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