2014-02-21 4 views
0

У меня есть 2 настройки в моих настройках: 1- PreferenceCategory 2-PreferenceX Когда я нажимаю PreferenceX, я добавляю новые настройки во время выполнения в PreferenceCategory. Но когда я поворачиваю устройство или убиваю приложение, снова заново его открываем: Я не могу найти все новые настройки, которые у меня есть во время выполнения. Я попытался использовать saveHierarchyState & restoreHierarchyState для данной preferenceCategory, но все еще не могу заставить его работать.Android runtime Предпочтения теряются при повороте устройства

Вот пример моего кода:

мой файл 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

Поворот вызывает перезагрузку.

Когда устройство повернуто, это происходит.
OnPause -> OnCreate (со старым savedInstanceState) ... -> OnPause -> OnCreate (новая savedInstanceState)

Это означает 2 активности перезагрузки циклов (с differtent savedInstanceState) для 1 поворота.
(я попробовал этот код)

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() используется для создания Предпочтения, элементы будут загружены, но стили (или состояние) неверны. (Если загружен загруженный элемент, отображается правильный текст.)

+0

Спасибо за ваш ответ, я добавил код onPause в код выше, но он не работает, когда я поворачиваю устройство, я все еще не вижу новых добавленных настроек , Более того, согласно моему первому коду, метод onSaveInstanceState был вызван обычно после перераспределения активности. –

+0

Спасибо за ваше обновление. Я принял ваше предлагаемое альтернативное решение, и он отлично работает со мной. Для стиля ошибки, о котором вы упомянули, мне удалось исправить его, изменив контекст, который используется при восстановлении в mehtod Load, чтобы быть предпочтительным = new Preference (this); Пожалуйста, отредактируйте свой ответ соответственно, чтобы я мог проверить его как правильный ответ, и я думаю, что в вашем ответе нет необходимости в первой части, так как это очень запутанно. –

+0

Благодарим вас за ваши комментарии. Я обновил свой ответ. – Toris

Смежные вопросы