【问题标题】:Android - save value of member field in Fragment classAndroid - 在 Fragment 类中保存成员字段的值
【发布时间】:2015-07-12 10:53:30
【问题描述】:

每次显示Fragment 时,我都会尝试在Fragment 类中使用boolean 做某事。

示例

我的应用启动,第一次打开FirstFragmentboolean 总是true,然后我有一个if 子句来检查它的值:

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

然后,第一次,当FirstTimetrue 时,我会执行诸如转到另一个Fragment 之类的操作。当我返回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 有什么误解?
有什么办法吗?

【问题讨论】:

  • 你有应用类吗?如果是这样保存在那里
  • @Elltz 你是什么意思?
  • 我的意思是你有布尔问题吗?那么一个简单的方法是创建一个单例类,只要您的片段和活动都还活着,它就会一直挂起,并在该类中创建变量,例如扩展 Application 的类

标签: java android android-fragments sharedpreferences android-lifecycle


【解决方案1】:

您假设只要应用程序还活着,Fragment 实例就会一直存在。这是一个合理的假设,如果该假设为真,您的方法将可以正常工作。

不幸的是,Fragment 在退回到后台时被销毁,并在返回前台时重新创建。这就是它看起来“刷新”的原因。 Activity 并非如此。当Activity 退到后台时,它不会立即被销毁。而是在当前任务的backstack上维护一段时间,如果回到前台,就是同一个实例。

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

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

    @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");
    }
    
  • 在全局常量类中声明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.

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

【讨论】:

  • 我已经尝试过 GlobalConstant 方法,但它仍然通过 if 和 onSaveInstance 方法,我不明白我该怎么做。我应该把 FirstTime 像 Boolean FirstTime = true;然后做这些事情?
  • 没关系,我明白了,它帮助我解决了其他问题,再次成为大师@Y.S.我很自豪这里有像你这样的人。谢谢你:)
  • 我会研究你的问题,如果有必要我会赏金你的问题以获得一个好的答案:P,如果可能的话,也和你的朋友谈谈尝试回答this question: P 他们说是我服务器端的问题,但我不这么认为...
  • this@Y.S. :P 希望有人能帮助你!
  • 你值得拥有更多;)
【解决方案2】:

简单的解决方案,将布尔值设置为静态。

这当然不符合编程的良好做法。

为了更直接地回答您的问题,我假设片段和活动被销毁并创建了新实例,因此布尔值再次设置为 true。因此,通过将变量设为静态,它的状态将在该类的所有实例中保持不变。

【讨论】:

  • 不需要set & get?
  • 如果你把它公开然后不行。
  • 不要让它静态化。保存onSaveInstanceState(Bundle) 中的值
  • @JaredRummler 我该怎么做?
  • 正如我所提到的,如果您要完全重新启动应用程序,则此方法将不起作用。
猜你喜欢
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多