Android运行时首选项在设备轮换时丢失

时间:2014-02-21 22:47:34

标签: android-preferences

我的设置中有2个首选项:1- PreferenceCategory 2-PreferenceX 当我按PreferenceX时,我在运行时将新的首选项添加到PreferenceCategory中。 但是当我旋转设备或杀死我的应用程序然后再次重新打开它: 我无法在运行时找到所有新的首选项。 我试图使用saveHierarchyState&给定preferenceCategory的restoreHierarchyState但仍无法使其工作。

以下是我的代码示例:

我的preferences.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory
        android:key="myCat"
        android:title="Example list"
        android:summary="This list is empty by default" />

    <Preference
        android:key="button"
        android:title="Example button"
        android:summary="When clicked this adds an item to the list" />

</PreferenceScreen>

这是我的MainActivity代码:

package com.example.testpreferences;

import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;

public class MainActivity extends PreferenceActivity {

    private int counter=0;
    private PreferenceGroup  pg;
    /** Called when the activity is first created. */
    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

       pg = (PreferenceGroup) getPreferenceScreen().findPreference("myCat");

        getPreferenceScreen().findPreference("button").setOnPreferenceClickListener(new OnPreferenceClickListener() {

            @Override
            public boolean onPreferenceClick(Preference a_preference) {


                Preference preference = new Preference(getApplicationContext());
                preference.setTitle("Item" + counter);
                preference.setKey("key"+counter);
                counter++;
                pg.addPreference(preference);

                return true;
            }
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        pg.saveHierarchyState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle state) {
        if (null != state) {
            pg.restoreHierarchyState(state);

        }else
            super.onRestoreInstanceState(state);
    }
}

尝试旋转设备,您将采用我所描述的错误行为。 如何保持在运行时添加的新首选项在屏幕旋转时显示?

1 个答案:

答案 0 :(得分:1)

旋转会导致活动重启。

当设备旋转时,会发生这种情况 onPause - &gt; onCreate(使用旧的savedInstanceState)... - &gt; onPause - &gt; onCreate(较新的savedInstanceState)

对于1次旋转,这意味着2次活动重启循环(使用differtent savedInstanceState) (我试过这段代码)

private int bootCounter = 0;

onCreate(...) { // watch savedInstanceState
    if (null != savedInstanceState) {
        bootCounter = savedInstanceState.getInt("bootCounter");
        bootCounter++;
    }
}

onSaveInstanceState(...) {
    ...
    outState.putInt("bootCounter", bootCounter);
}

也许是同样的问题:
Home key press behaviour
我没有测试过,但有一些关于#14的提示,#17:
Issue26658:Activity stack confused when launching app from browser
很长一点,但很多提示:
savedInstanceState always null


轮换。 (使用SharedPreferences保存首选项)

public class MainActivity extends PreferenceActivity
{
    private int counter = 0;
    private PreferenceGroup pg;

    /** Called when the activity is first created. */
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Load();

        getPreferenceScreen().findPreference("button").setOnPreferenceClickListener(new OnPreferenceClickListener()
        {
            @Override
            public boolean onPreferenceClick(Preference a_preference)
            {
                // Preference preference = new Preference(getApplicationContext());
                Preference preference = new Preference(MainActivity.this);
                preference.setTitle("Item" + counter);
                preference.setKey("key" + counter);
                counter++;
                pg.addPreference(preference);

                return true;
            }
        });
    }

    private void Save()
    {
        SharedPreferences sharedPreferences;
        Editor editor;
        Preference preference;
        int keyCount;

        if (null != pg)
        {
            sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
            if (null != sharedPreferences)
            {
                editor = sharedPreferences.edit();
                keyCount = pg.getPreferenceCount();
                // editor.putInt("keyCount", keyCount);
                // editor.putInt("counter", counter);
                for (int i = 0; i < keyCount; i++)
                {
                    preference = pg.getPreference(i);
                    editor.putString(preference.getKey(), preference.getTitle().toString());
                }
                // Save to file
                // *** commit() will block caller thread ***
                editor.commit();
            }
        }
    }

    @SuppressWarnings("deprecation")
    private void Load()
    {
        SharedPreferences sharedPreferences;
        Preference preference;
        Map<String, ?> data;

        addPreferencesFromResource(R.xml.preferences);
        pg = (PreferenceGroup) getPreferenceScreen().findPreference("myCat");
        counter = 0;
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        if (null != sharedPreferences)
        {
            // load from SharedPreferences
            data = sharedPreferences.getAll();

            // this doesn't keep original order
            for (Entry<String, ?> kv : data.entrySet())
            {
                if (String.class != kv.getValue().getClass())
                {
                    continue;
                }
                // fixed: getApplicationContext() causes style bug. (*1)
                // preference = new Preference(getApplicationContext());
                preference = new Preference(MainActivity.this);
                preference.setTitle(new String((String) kv.getValue()));
                preference.setKey(new String(kv.getKey()));
                preference.setEnabled(true);
                counter++;
                pg.addPreference(preference);
            }
            // counter = sharedPreferences.getInt("counter", counter);
            onContentChanged();
        }
    }

    //@Override
    //protected void onSaveInstanceState(Bundle outState)
    //{
    //    super.onSaveInstanceState(outState);
    //}

    @Override
    protected void onPause()
    {
        super.onPause();
        Save();
    }

}

(* 1):固定。
如果使用getApplicationContext()创建Preference,则将加载项目但样式(或状态)不正确。 (如果触摸了加载的项目,则会显示正确的文本。)