Android - 保存的活动/片段状态永远不会清除

时间:2015-12-27 07:53:01

标签: android android-fragments sharedpreferences android-lifecycle

我有一个由Fragments组成的Android应用程序,我已正确保存状态。问题是它有点太多好;-)。我将输入一些EditText元素的输入,然后通过#34; onSaveInstanceState()"中的SharedPrefs保存。方法,然后点击"任务管理器"或者" Switch App"手机上的按钮(有两个重叠的矩形作为图标)并向左滑动以关闭我的应用程序。如果我然后转到App Drawer并重新运行应用程序,那么保存的输入仍然存在。我正在清除" onDestroy()"中保存的实例状态。方法也是,但显然当"关闭"来自该任务管理器的应用程序(通过记录确认)。

这里有什么建议吗?我没有的其他应用程序表现出这种行为。我希望当用户通过任务管理器关闭应用程序时以及可能在一段时间后关闭已保存的输入。 有关状态处理标准做法的任何想法都在这里吗?

我测试了一些应用程序,并注意到默认的联系人应用程序实际上会保存一个新的联系人,如果你开始一个新的联系人,并在明确保存之前切换到另一个应我想我可以这样做,但我不愿意。

以下是特定片段的一些相关代码;非常感谢您的任何帮助。

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);

    Log.v(Tag, "onSaveInstanceState()");

    saveInstanceState();
}

@Override
public void onResume() {
    super.onResume();

    Log.v(Tag, "onResume()");

    restoreInstanceState();
}

@Override
public void onDestroy() {
    super.onDestroy();

    Log.v(Tag, "onDestroy()");

    clearInstanceState();
}

private void saveInstanceState() {
    Log.v(Tag, "saveInstanceState()");

    // get entered data
    String name = mTxtName.getText().toString();
    String notes = mTxtNotes.getText().toString();

    // save data in Shared Prefs
    PreferenceManager.getDefaultSharedPreferences(mContext)
            .edit()
            .putInt(KeyAmmunitionId, mAmmunitionId)
            .putString(KeyName, name)
            .putString(KeyNotes, notes)
            .putString(StringUtils.CurrentFragmentKey, Tag)
            .commit();
}

private void restoreInstanceState() {
    Log.v(Tag, "restoreInstanceState()");

    mTxtName = (EditText)getActivity().findViewById(R.id.frag_manage_ammunition_txtName);
    mTxtNotes = (EditText)getActivity().findViewById(R.id.frag_manage_ammunition_txtNotes);

    if (PreferenceManager.getDefaultSharedPreferences(mContext).contains(KeyName)) {
        String ammunitionName = PreferenceManager.getDefaultSharedPreferences(mContext).getString(KeyName, StringUtils.EMPTY_STRING);

        mTxtName.setText(ammunitionName);
    }

    if (PreferenceManager.getDefaultSharedPreferences(mContext).contains(KeyNotes)) {
        String ammunitionNotes = PreferenceManager.getDefaultSharedPreferences(mContext).getString(KeyNotes, StringUtils.EMPTY_STRING);

        mTxtNotes.setText(ammunitionNotes);
    }
}

private void clearInstanceState() {
    Log.v(Tag, "clearInstanceState()");

    PreferenceManager.getDefaultSharedPreferences(mContext)
            .edit()
            .remove(KeyAmmunitionId)
            .remove(KeyName)
            .remove(KeyNotes)
            .commit();
}

1 个答案:

答案 0 :(得分:0)

而不是使用SharedPrefs,我发现保留其状态的内部无头片段更容易实现/更清洁。

在你的片段类中,你有这个类....

/**
 * "Headless" Fragment that retains state information between
 * configuration changes.
 */
public class RetainedFragment extends Fragment {
    /**
     * internal storage to be kept put here
     */

    // assuming the only 'view' in the parent fragment is this editText with some string value.
    String editTextValue;

    public RetainedFragment(){
        editTextValue = ""; //init values on first time in. 
    }

    /**
     * Hook method called when a new instance of Fragment is
     * created.
     *
     * @param savedInstanceState
     *            object that contains saved state information.
     */
    @Override
        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Ensure the data survives runtime configuration changes.
        setRetainInstance(true);

    }

    // have getter/setter methods

然后在你的外面的fagment中创造' UI基于存储在内部无头片段中的值。

... OR

您可以使用我们想出的RetainedFragmentManager。它有点不稳定,起初可能有点混乱,但它是一个无头片段,允许你以类似hashmap的方式存储java对象,它们将在配置更改中持续存在,但如果不存在则不存在您的应用已完全关闭等。

https://github.com/douglascraigschmidt/POSA-15/blob/master/ex/ImageDownloads/src/vandy/mooc/common/RetainedFragmentManager.java