Як використовувати приклад onSavedInstanceState, будь ласка


110

Я розгублений, коли справа зводиться до економії держави. Тож я знаю, що onSaveInstanceState(Bundle)називається, коли діяльність буде знищена. Але як ви зберігаєте свою інформацію в ній і повертаєте її до початкового стану onCreate(Bundle savedInstanceState)? Я не розумію, як цей пакет буде відновити інформацію. Було б корисно, якщо хтось може навести приклад. Посібник Dev не дуже добре пояснює це.

public class Conversation extends Activity {
    private ProgressDialog progDialog;
    int typeBar;
    TextView text1;
    EditText edit;
    Button respond;
    private String name;
    private String textAtView;
    private String savedName;

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setContentView(R.layout.dorothydialog);
        text1 = (TextView)findViewById(R.id.dialog);
        edit = (EditText)findViewById(R.id.repsond);
        respond = (Button)findViewById(R.id.button01);

        if(savedInstanceState != null){
            savedInstanceState.get(savedName);
            text1.setText(savedName);
        }
        else{
            text1.setText("Hello! What is your name?");
            respond.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    name = edit.getText().toString();
                    text1.setText("Nice to meet you "+ name);
                }   
            });
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putString(savedName, name);
    }
}

text1.setText (записанийInstanceState.getString (збережений назви));
Spidy

@Spidy Що з OnBackpress? Як би я відреагував на це зв’язкою?
ходок

Ви б не зробили. Коли користувач натискає кнопку назад. Діяльність вбита. Використовуйте базу даних для постійного зберігання даних. Використовуйте пакет для повернення перезапущеної програми до її попереднього стану.
Spidy

Відповіді:


198

Це Bundleконтейнер для всієї інформації, яку ви хочете зберегти. Ви використовуєте функції put *, щоб вставити в нього дані. Ось короткий список (є більше) функцій put, які ви можете використовувати для зберігання даних у Bundle.

putString
putBoolean
putByte
putChar
putFloat
putLong
putShort
putParcelable (used for objects but they must implement Parcelable)

У вашій onCreateфункції це Bundleпередається програмі. Найкращий спосіб перевірити, чи програма перезавантажується чи запускається вперше:

if (savedInstanceState != null) {
    // Then the application is being reloaded
}

Щоб повернути дані, використовуйте функції get * так само, як і функції put *. Дані зберігаються як пара імен-значення. Це як хешмап. Ви надаєте ключ і значення, тоді, коли потрібно повернути значення, ви віддаєте ключ і функція отримує значення. Ось короткий приклад.

@Override
public void onSaveInstanceState(Bundle outState) {
   outState.putString("message", "This is my message to be reloaded");
   super.onSaveInstanceState(outState);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String message = savedInstanceState.getString("message");
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
}

Ваше збережене повідомлення буде підсмажене на екрані. Сподіваюся, це допомагає.


14
onSaveInstanceState () викликається перед призупиненням вашої активності. Тож будь-яку інформацію, яка йому потрібна після її потенційного знищення, можна отримати із збереженого пакету
Дідерік

@Spidy Awesome! Ви просто насправді змусили мене зрозуміти все про в’язку! так що я здогадуюсь outState передається назад в пакет збереженихInstanceState? Правильно?
ходок

Так. Пакет outState передається назад як збереженийInstanceState Bundle
Spidy

1
@tj walker - Ще один чудовий ресурс - це технічні довідники. Pro Android 3 - це дешевий, але широкий ресурс, який ви можете отримати на Amazon
Spidy

@Spidy Я опублікував свій код діяльності вище, щоб вас побачили. Можливо, ви можете мені повідомити, якщо я врятую своє право, як ви запропонували.
ходок

34

Одне головне зауваження, про яке повинні знати всі нові розробники Android, - це те, що будь-яка інформація у Віджетах (TextView, Кнопках тощо) Android буде зберігатися автоматично автоматично, доки ви призначите їм ідентифікатор. Отже, це означає, що про більшу частину штату інтерфейсу доглядають без проблем. Тільки тоді, коли вам потрібно зберігати інші дані, це стає проблемою.

З Документів Android :

Єдина необхідна вам робота - надати унікальний ідентифікатор (з атрибутом android: id) для кожного віджета, який ви хочете зберегти його стан. Якщо у віджета немає ідентифікатора, він не може зберегти його стан


1
Ну це справді правда? Тому що я маю активність з переглядом кнопки та редагуванням тексту. Якщо додаток знищено або вбито, все повернеться у початковий стан. У моїй програмі тексти textView змінюються кожного разу, коли користувач натискає кнопку.
ходок

Неточна документація? У мене ніколи не було View, крім власної інформації. Найкраще, на мою думку, зберегти всю свою інформацію самостійно.
Spidy

2
Якщо ваша мета - зберегти інформацію наSaveInstanceState, це НЕ місце для цього. Це тому, що немає гарантії, що вона буде називатися (див. Документи). Натомість слід писати в базу даних, SharedPreferences тощо. Так, ця інформація є точною. Найкращий спосіб перевірити, чи підтримується ваш інтерфейс користувача таким чином, - це повернути ваш дисплей, коли зміни орієнтації перезапускають ваш onCreate і використовують пакет для відновлення стану.
Кіт Адлер

@Nissan Fan Ви можете навести приклад, як павук зробив вище? З розділеними префіксами і все? Спасибі
ходок

Найкращі приклади, відверто кажучи, виходять із документації. developer.android.com/guide/topics/data/data-storage.html#pref
Кіт Адлер

6

Хороша інформація: вам не потрібно перевіряти, чи об'єкт Bundle є нульовим у методі onCreate (). Використовуйте метод onRestoreInstanceState (), який система викликає після методу onStart (). Система викликаєReRerereInstanceState (), тільки якщо є збережений стан для відновлення, тому вам не потрібно перевіряти, чи пакет недійсний


5

Інформація про магазин:

static final String PLAYER_SCORE = "playerScore";
static final String PLAYER_LEVEL = "playerLevel";

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(PLAYER_SCORE, mCurrentScore);
    savedInstanceState.putInt(PLAYER_LEVEL, mCurrentLevel);

// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}

Якщо ви не хочете відновити інформацію у своєму методі onCreate:

Ось приклади: Відтворення діяльності

Замість того, щоб відновити стан під час onCreate (), ви можете вибрати впровадження OnRestoreInstanceState (), яке система викликає після методу onStart (). Система викликаєReRerereInstanceState (), тільки якщо є збережений стан для відновлення, тому вам не потрібно перевіряти, чи пакет недійсний

public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);

// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(PLAYER_SCORE);
mCurrentLevel = savedInstanceState.getInt(PLAYER_LEVEL);
}

0

В основному onSaveInstanceState (Bundle outBundle) дасть вам пакет. Подивившись на клас Bundle, ви побачите, що ви можете помістити в нього багато різних речей. При наступному виклику onCreate () ви просто повернете цей пакет як аргумент. Потім ви зможете прочитати свої цінності ще раз і відновити свою активність.

Скажімо, у вас є діяльність з EditText. Користувач написав текст всередині нього. Після цього система викликає ваш onSaveInstanceState (). Ви читаєте текст з EditText і записуєте його в пакет через Bundle.putString ("edit_text_value", theValue).

Тепер onCreate називається. Ви перевіряєте, чи наданий пакет не є нульовим. Якщо це так, ви можете відновити своє значення за допомогою Bundle.getString ("edit_text_value") і повернути його у свій EditText.


0

Це для отримання додаткової інформації.

Уявіть собі цей сценарій

  1. ActivityA запуск ActivityB.
  2. ActivityB запустив новий ActivityAPrime від

    Intent intent = new Intent(getApplicationContext(), ActivityA.class);
    startActivity(intent);
  3. ActivityAPrime не має відношення до ActivityA.
    У цьому випадку пакет у ActivityAPrime.onCreate () буде нульовим.

Якщо ActivityA і ActivityAPrime повинні бути однаковими діями замість різних видів діяльності, ActivityB повинен викликати закінчення (), ніж використання startActivity ().


просто для уточнення, у вашому прикладі, це ActivityA == ActivityA екземпляр 1 та ActivityAPrime == ActivityA екземпляр 2? також, коли ви говорите: "ActivityB повинен викликати закінчення (), ніж використання startActivity ()." ви маєте на увазі: (1) ActivationB повинен викликати закінчення (), а потім використовувати startActivity () згодом (2) або ActivityB повинен викликати закінчення (), а не використовувати startActivity () взагалі? якщо ви мали на увазі варіант 2, то як би ви запропонували комусь перезапустити ту саму ActivityA instance1, щоб ви могли завантажувати дані, що містяться до знищення / завершення? Спасибі
cjayem13

ActivityA і ActivityAPrime - це один клас, але різні випадки. У цьому сценарії ActivityA ще не закінчив свій бізнес, в середині він створив і запустив ActivityB, тому коли ActivityB закінчиться, ActivityA повинен продовжувати свою роботу. У цьому випадку неправильно називати startActivity, і очікуючи, що ActivityA і ActiviyAPrime будуть однаковими. тому ми не повинні перезапускати ActivityA, просто закінчіть ActivityB і нехай ActivityA відновить свою роботу ...
ken

0

Якщо дані не завантажені, savedInstanceStateвикористовуйте наступний код.
Проблема в тому, що виклик URL-адреси полягає не в повному виконанні, тому перевірте, чи завантажуються дані, щоб показати значення instanceState.

//suppose data is not Loaded to savedInstanceState at 1st swipe
if (savedInstanceState == null && !mAlreadyLoaded){
    mAlreadyLoaded = true;
    GetStoryData();//Url Call
} else {
    if (listArray != null) {  //Data Array From JsonArray(ListArray)
        System.out.println("LocalData  " + listArray);
        view.findViewById(R.id.progressBar).setVisibility(View.GONE);
    }else{
        GetStoryData();//Url Call
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.