Úsporné Android stav činnost využívající Uložit instance státu

hlasů
2k

Byl jsem pracoval na Android SDK platformy, a to je trochu nejasné, jak ušetřit stav žádosti je. Takže vzhledem k tomu, tento malý re-nástrojů v oblasti politiky ‚Hello, Android‘ Například:

package com.android.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {

  private TextView mTextView = null;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTextView = new TextView(this);

    if (savedInstanceState == null) {
       mTextView.setText(Welcome to HelloAndroid!);
    } else {
       mTextView.setText(Welcome back.);
    }

    setContentView(mTextView);
  }
}

Myslel jsem, že to bude stačit k nejjednodušším případě, ale vždy odpoví první zprávy, bez ohledu na to, jak se lze pohybovat od aplikace.

Jsem si jistý, že řešení je tak jednoduché, jak naléhavé onPausenebo něco takového, ale já jsem byl postrkování daleko v dokumentaci po dobu 30 minut nebo tak, a nic nenašli zřejmý.

Položena 30/09/2008 v 05:41
zdroj uživatelem
V jiných jazycích...                            


29 odpovědí

hlasů
2k

Je třeba potlačit onSaveInstanceState(Bundle savedInstanceState)a zapisovat hodnoty stavu aplikací, které chcete změnit na Bundleparametru, jako je tento:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
  super.onSaveInstanceState(savedInstanceState);
  // Save UI state changes to the savedInstanceState.
  // This bundle will be passed to onCreate if the process is
  // killed and restarted.
  savedInstanceState.putBoolean("MyBoolean", true);
  savedInstanceState.putDouble("myDouble", 1.9);
  savedInstanceState.putInt("MyInt", 1);
  savedInstanceState.putString("MyString", "Welcome back to Android");
  // etc.
}

Svazek je v podstatě způsob, jak ukládání NVP ( „Name-Value Pair“) mapy, a to dostane předán do onCreate()a také onRestoreInstanceState(), kde byste extrahovat hodnoty, jako je tento:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  // Restore UI state from the savedInstanceState.
  // This bundle has also been passed to onCreate.
  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
  double myDouble = savedInstanceState.getDouble("myDouble");
  int myInt = savedInstanceState.getInt("MyInt");
  String myString = savedInstanceState.getString("MyString");
}

Ty by obvykle používají tuto techniku ​​k ukládání hodnot instancí pro danou aplikaci (výběry, neuložený text, atd.)

Odpovězeno 30/09/2008 v 07:12
zdroj uživatelem

hlasů
369

savedInstanceStateJe určen pouze pro ukládání stavu spojeného s aktuální instanci aktivitu, například pro současnou trasu nebo výběru informací, takže pokud Android zničí a znovu určité činnosti, může se vrátit, jak to bylo předtím. Naleznete v dokumentaci onCreateaonSaveInstanceState

Pro více informací dlouhým poločasem rozpadu státu, zvažte použití SQLite databáze, soubor nebo preference. Viz Ukládání trvalý stav .

Odpovězeno 30/09/2008 v 06:03
zdroj uživatelem

hlasů
358

Všimněte si, že není bezpečné použití onSaveInstanceStatea onRestoreInstanceState pro perzistentních dat , podle dokumentace o činnosti států v http://developer.android.com/reference/android/app/Activity.html .

V dokumentu se uvádí (v sekci ‚činností životního cyklu‘):

Všimněte si, že je důležité ukládat trvalá data v onPause()místo onSaveInstanceState(Bundle) , protože později není součástí životního cyklu zpětné volání, takže nebude nazýván v každé situaci, jak je popsáno v dokumentaci.

Jinými slovy, dát své uložit / obnovit kód perzistentních dat onPause()a onResume()!

EDIT : Pro bližší vysvětlení, tady je onSaveInstanceState()dokumentace:

Tato metoda je volána před aktivitou mohou být usmrcena tak, že když se vrátí někdy v budoucnu mohou obnovit svůj stav. Například, pokud je činnost B zahájena před aktivitou, a v určitém okamžiku aktivitou je zabit na vrácení prostředků, aktivita a bude mít možnost uložit aktuální stav svého uživatelského rozhraní pomocí této metody, takže když se uživatel vrátí do činnosti a, stav uživatelského rozhraní může být obnovena pomocí onCreate(Bundle)nebo onRestoreInstanceState(Bundle).

Odpovězeno 26/05/2010 v 00:22
zdroj uživatelem

hlasů
167

Můj kolega napsal článek vysvětlující žaloba na zařízení se systémem Android, včetně vysvětlení činnosti životního cyklu a Státní informační, jak ukládat informace o stavu a uložení do státu Bundlea SharedPreferencesa se podívat na zde .

Tento článek se zabývá třemi přístupy:

Ukládat místní data proměnná / kontrolní UI pro životnost aplikace (tj dočasně) pomocí instance státní Bundle

[Code sample – Store State in State Bundle]
@Override
public void onSaveInstanceState(Bundle savedInstanceState) 
{
  // Store UI state to the savedInstanceState.
  // This bundle will be passed to onCreate on next call.  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  savedInstanceState.putString(“Name”, strName);
  savedInstanceState.putString(“Email”, strEmail);
  savedInstanceState.putBoolean(“TandC”, blnTandC);

  super.onSaveInstanceState(savedInstanceState);
}

Ukládat místní data proměnná / kontrolní UI mezi instancemi aplikace (tj trvale) pomocí sdílených předvoleb

[Code sample – Store State in SharedPreferences]
@Override
protected void onPause() 
{
  super.onPause();

  // Store values between instances here
  SharedPreferences preferences = getPreferences(MODE_PRIVATE);
  SharedPreferences.Editor editor = preferences.edit();  // Put the values from the UI
  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  editor.putString(“Name”, strName); // value to store
  editor.putString(“Email”, strEmail); // value to store
  editor.putBoolean(“TandC”, blnTandC); // value to store    
  // Commit to storage
  editor.commit();
}

Udržet instance objektu žije v paměti mezi činnosti v rámci celého života aplikace využívající zachováno Non-Configuration Instance

[Code sample – store object instance]
private cMyClassType moInstanceOfAClass;// Store the instance of an object
@Override
public Object onRetainNonConfigurationInstance() 
{
  if (moInstanceOfAClass != null) // Check that the object exists
      return(moInstanceOfAClass);
  return super.onRetainNonConfigurationInstance();
}
Odpovězeno 27/08/2010 v 14:54
zdroj uživatelem

hlasů
125

Jedná se o klasický ‚chyták‘ vývoje Android. Existují dva problémy:

  • K dispozici je subtilní Android Framework chyba, která značně komplikuje řízení zásobníku aplikací během vývoje alespoň na starších verzích (ne úplně jistý, jestli / když / jak byla stanovena). Budu diskutovat pod tuto chybu.
  • ‚Normální‘ nebo určené způsob, jak zvládnout tento problém, je sama o sobě poměrně složitá s dualitou onPause / onResume a onSaveInstanceState / onRestoreInstanceState

Listování napříč všemi těmito závity, mám podezření, že hodně z vývojářů časových hovoříme o těchto dvou různých otázek najednou ... tedy veškerý zmatek a zprávy o „to není práce pro mě.“

Za prvé, aby vyjasnila ‚zamýšlený‘ chování: onSaveInstance a onRestoreInstance jsou křehké a jen na přechodném stavu. Zamýšlená použití (afaict) je zpracovat rekreační činností, pokud je telefon otočen (změna orientace). Jinými slovy, zamýšlené využití je, když je vaše aktivity stále logicky ‚nahoře‘, ale stále je třeba reinstantiated systémem. Uložený Bundle není trvalé mimo proces / paměti / GC, takže si můžete opravdu spolehnout na to, pokud vaše činnost přejde do pozadí. Ano, snad paměť vaše aktivita bude přežít svůj výlet do pozadí a únik GC, ale to není spolehlivé (a není ani předvídatelný).

Takže pokud máte situaci, kdy existuje významný ‚pokrok uživatel‘ nebo stav, který by měl být trvalé mezi ‚vypuštění‘ vaší aplikace, vedení je použití onPause a onResume. Musíte si vybrat a připravit trvalé paměti sami.

ALE - tam je velmi matoucí chyba, která komplikuje to všechno. Podrobnosti jsou uvedeny zde:

http://code.google.com/p/android/issues/detail?id=2373

http://code.google.com/p/android/issues/detail?id=5277

Zjednodušeně řečeno, pokud vaše aplikace spuštěna s příznakem SingleTask, a pak o něco později jej spustit na domovské obrazovce nebo v nabídce Spouštěč, pak následné vyvolání vytvoří nový úkol ... budete skutečně mít dvě různé instance aplikace obývat stejný stack ... který dostane velmi podivné velmi rychle. Zdá se to stane, když spustíte aplikaci v průběhu vývoje (tj z Eclipse nebo IntelliJ), takže vývojáři dostat do tohoto hodně. Ale i přes některé mechanismy aktualizací App Store (tak budou mít dopad na vaši uživatelé stejně).

bojoval I přes tyto závity několik hodin předtím, než jsem si uvědomil, že moje hlavní otázka byla tato chyba, není zamýšlený rámec chování. Velkou writeup ařešením (UPDATE: viz níže) se zdá být z uživatelského @kaciula na tuto odpověď:

stisk tlačítka chování Home

UPDATE 06. 2013 : O několik měsíců později, jsem konečně našel ‚správné‘ řešení. Nemusíte se řídit některý stavovou startedApp vlajek sami, můžete to zjistit z rámce a kauci odpovídajícím způsobem. Používám to se blížit k začátku mého LauncherActivity.onCreate:

if (!isTaskRoot()) {
    Intent intent = getIntent();
    String action = intent.getAction();
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {
        finish();
        return;
    }
}
Odpovězeno 20/10/2012 v 00:47
zdroj uživatelem

hlasů
70

onSaveInstanceStateje volána, když systém potřebuje paměť a zabije aplikace. To není volána, když uživatel právě ukončí aplikaci. Takže myslím, že stav aplikace by měla být rovněž uloženy v onPauseMělo by být uložen do určité trvalé úložiště, jako PreferencesneboSqlite

Odpovězeno 07/05/2010 v 01:21
zdroj uživatelem

hlasů
59

Obě metody jsou užitečné a platný a oba se nejlépe hodí pro různé scénáře:

  1. Uživatel ukončí aplikaci a znovu otevře jej později, ale aplikace je třeba ji znovu načíst data z posledního zasedání - to vyžaduje trvalý přístup pro ukládání například používáte SQLite.
  2. Uživatel přepne aplikaci a poté se vrátí na původní a chce vyzvednout tam, kde přestali - uložení a obnovení svazků dat (jako jsou aplikační data stavu) v onSaveInstanceState()a onRestoreInstanceState()je obvykle dostačující.

Máte-li uložit data stavu v trvalém způsobem, že lze vrátit v onResume()Or onCreate()(nebo vlastně na jakékoliv životního cyklu hovoru). To může, ale nemusí být žádoucí chování. Pokud ji uložit do svazku v InstanceState, pak je přechodná a je vhodný pouze pro ukládání dat pro použití stejného uživatelského ‚sezení‘ (I používat termín zasedání volně), ale ne mezi ‚sezení‘.

Není pravda, že jeden přístup je lepší než ostatní, stejně jako všechno, je to jen důležité pochopit, jaké chování budete potřebovat a vybrat nejvhodnější přístup.

Odpovězeno 27/06/2011 v 17:17
zdroj uživatelem

hlasů
50

Myslím, že jsem našel odpověď. Dovolte mi říct, co jsem udělal v jednoduchých slov:

Předpokládejme, že mám dvě aktivity, aktivity1 a activity2 a já přechodu z aktivity1 do activity2 (jsem udělal nějaké práce v activity2) a zase zpět k aktivitě 1. Kliknutím na tlačítko v aktivity1. Právě v této fázi jsem se chtěl vrátit do activity2 a chci vidět svou activity2 ve stejném stavu, kdy jsem naposledy opustil activity2.

Z výše uvedeného scénáře, co jsem udělal, je, že v manifestu jsem udělal nějaké změny, jako je tento:

<activity android:name=".activity2"
          android:alwaysRetainTaskState="true"      
          android:launchMode="singleInstance">
</activity>

A v aktivity1 v případě stisknutí tlačítka I udělal takhle:

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.setClassName(this,"com.mainscreen.activity2");
startActivity(intent);

Av activity2 v případě stisknutí tlačítka jsem s ním takhle:

Intent intent=new Intent();
intent.setClassName(this,"com.mainscreen.activity1");
startActivity(intent);

A teď, co se stane je, že bez ohledu nebudou ztraceny změny jsme provedli v activity2 a můžeme prohlédnout activity2 ve stejném stavu, jak jsme opustili dříve.

Věřím, že to je odpověď, a to funguje dobře pro mě. Opravte mě, jestli se mýlím.

Odpovězeno 05/02/2012 v 12:35
zdroj uživatelem

hlasů
50

Ukládání stavu je kludge v nejlepším případě, pokud jde o mě. Pokud potřebujete uložit perzistentní data, stačí použít SQLite databáze. Android umožňuje SOOO snadné.

Něco takového:

import java.util.Date;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class dataHelper {

    private static final String DATABASE_NAME = "autoMate.db";
    private static final int DATABASE_VERSION = 1;

    private Context context;
    private SQLiteDatabase db;
    private OpenHelper oh ;

    public dataHelper(Context context) {
        this.context = context;
        this.oh = new OpenHelper(this.context);
        this.db = oh.getWritableDatabase();
    }

    public void close()
    {
        db.close();
        oh.close();
        db = null;
        oh = null;
        SQLiteDatabase.releaseMemory();
    }


    public void setCode(String codeName, Object codeValue, String codeDataType)
    {
        Cursor codeRow = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        String cv = "" ;

        if (codeDataType.toLowerCase().trim().equals("long") == true)
        {
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            cv = String.valueOf(((Date)codeValue).getTime());
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            String.valueOf(codeValue);
        }
        else
        {
            cv = String.valueOf(codeValue);
        }

        if(codeRow.getCount() > 0) //exists-- update
        {
            db.execSQL("update code set codeValue = '" + cv +
                "' where codeName = '" + codeName + "'");
        }
        else // does not exist, insert
        {
            db.execSQL("INSERT IGNORE  INTO code (codeName, codeValue, codeDataType) VALUES(" +
                    "'" + codeName + "'," +
                    "'" + cv + "'," +
                    "'" + codeDataType + "')" );
        }
    }

    public Object getCode(String codeName, Object defaultValue)
    {
        //Check to see if it already exists
        String codeValue = "";
        String codeDataType = "";
        boolean found = false;
        Cursor codeRow  = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        if (codeRow.moveToFirst())
        {
            codeValue = codeRow.getString(codeRow.getColumnIndex("codeValue"));
            codeDataType = codeRow.getString(codeRow.getColumnIndex("codeDataType"));
            found = true;
        }

        if (found == false)
        {
            return defaultValue;
        }
        else if (codeDataType.toLowerCase().trim().equals("long") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (long)0;
            }
            return Long.parseLong(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (int)0;
            }
            return Integer.parseInt(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            if (codeValue.equals("") == true)
            {
                return null;
            }
            return new Date(Long.parseLong(codeValue));
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            if (codeValue.equals("") == true)
            {
                return false;
            }
            return Boolean.parseBoolean(codeValue);
        }
        else
        {
            return (String)codeValue;
        }
    }


    private static class OpenHelper extends SQLiteOpenHelper {

        OpenHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE IF  NOT EXISTS code" +
            "(id INTEGER PRIMARY KEY, codeName TEXT, codeValue TEXT, codeDataType TEXT)");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
}

Jednoduchý volání po tom

dataHelper dh = new dataHelper(getBaseContext());
String status = (String) dh.getCode("appState", "safetyDisabled");
Date serviceStart = (Date) dh.getCode("serviceStartTime", null);
dh.close();
dh = null;
Odpovězeno 23/06/2011 v 18:07
zdroj uživatelem

hlasů
36

onSaveInstanceState()pro přechodné dat (obnovena v onCreate()/ onRestoreInstanceState()), onPause()pro trvalá data (obnoven v onResume()). Z Android technických prostředků:

onSaveInstanceState () je volána systémem Android v případě, že činnost je zastavena a může být zabit před tím, než se obnoví! To znamená, že by měl ukládat jakýkoli stát nezbytné znovu inicializovat ve stejném stavu, kdy je aktivita restartován. Je analogický k metodě OnCreate (), a ve skutečnosti savedInstanceState Bundle předán do onCreate () je stejný svazek, který konstrukt outState v metodě onSaveInstanceState ().

onPause () a onResume () jsou také bezplatné metody. onPause () je volána vždy, když skončí činnost, i když jsme podnítili, že (s úpravou () volání například). Budeme používat tento uložit aktuální poznámku zpět do databáze. Dobrá praxe je, aby propustila všechny prostředky, které mohou být uvolněny během onPause () stejně, aby zabírají méně prostředků, když je v pasivním stavu.

Odpovězeno 17/01/2012 v 19:28
zdroj uživatelem

hlasů
35

Obnovovat určité činnosti

Existuje několik scénářů, ve kterém je vaše činnost zničena kvůli normálnímu chování aplikace, jako je například, když uživatel stiskne tlačítko Back nebo vaše činnost signalizuje vlastní destrukci voláním finish(). Systém může také zničit svou aktivitu, pokud je to v současné době zastavena a nebyla používána delší dobu nebo v popředí činnost vyžaduje více zdrojů, takže systém musí vypnout procesy na pozadí obnovit paměť.

Když vaše activityje zničen, protože uživatel stiskne klávesu Back nebo activityskončí sama, koncepce systému této Activityinstance je navždy pryč, protože chování naznačuje, již není potřeba činnost. Je-li však systém ničí aktivitu vzhledem k systémovým omezením (spíše než normální chování aplikace), pak i když skutečná instance aktivita je pryč, systém si pamatuje, že existuje taková, že v případě, že uživatel přejde zpět na ní, systém vytvoří nový instance aktivity pomocí sady uložených dat, která popisuje stav činnosti, pokud to bylo destroyed. Uložená data, že systém používá obnovit předchozí stav je nazýván „instance stav“ a je sbírka dvojic klíč-hodnota uložená v objektu svazku.

Chcete-li uložit další údaje o stavu aktivity, je nutné přepsat metody zpětného volání onSaveInstanceState (). Systém volá tuto metodu když uživatel opouští svou aktivitu a předává jí objekt Bundle, které budou uloženy v případě, že vaše činnost je zničena neočekávaně. V případě, že systém musí znovu instance aktivity později prochází stejnou Bundle objekt jak onRestoreInstanceState()a onCreate()metody. zadejte popis obrázku zde

Vzhledem k tomu, systém začne zastavit svou činnost, zavolá onSaveInstanceState()(1), takže si můžete zadat dodatečnou státní údaje, které chcete uložit v případě, že instance aktivity musí být znovu. Je-li činnost zničena a stejný případ je třeba znovu, systém předává data stavu definované v (1), jak na onCreate()způsobu (2) a onRestoreInstanceState()metodou (3).

Zachránit svůj Activitystát

Jak se vaše aktivita začne zastavit, volá systém onSaveInstanceState(), takže vaše činnost může uložit informace o stavu se sbírkou párů klíč-hodnota. Výchozí implementace této metody ukládá informace o stavu zobrazení hierarchie dané činnosti, jako je například text v EditTextwidgetu nebo pozici posuvníku z A ListView.

Chcete-li uložit další informace o stavu pro vaše aktivity, je nutné zavést onSaveInstanceState()a přidat páry klíč-hodnota k objektu svazku. Například:

  static final String STATE_SCORE = "playerScore";
  static final String STATE_LEVEL = "playerLevel";

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

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

Upozornění: Vždy volejte na rodičovské provádění onSaveInstanceState()takže výchozí implementace může uložit stav hierarchie pohledu.

Obnovit svůj Activitystát

Je-li vaše činnost znovu poté, co bylo předtím zničena, můžete obnovit uložený stav z Bundle, že systém projde svou činnost. Jak onCreate()a onRestoreInstanceState()metody zpětného volání přijímat stejný Bundle, který obsahuje informace o stavu instance.

Vzhledem k tomu, onCreate()metoda se nazývá, zda je tento systém vytváří novou instanci své činnosti nebo obnovovat předchozí, je nutné zkontrolovat, zda je stav Bundle je null před pokusem o číst. V případě, že je nulový, pak systém je vytvoření nové instance činnosti, namísto obnovení předchozí, který byl zničen.

Například, tady je návod, jak můžete obnovit některé státní údaje onCreate():

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState); // Always call the superclass first

 // Check whether we're recreating a previously destroyed instance
 if (savedInstanceState != null) {
    // Restore value of members from saved state
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
 } else {
    // Probably initialize members with default values for a new instance
 }

 }

Namísto obnovení stavu při onCreate()můžete vybrat implementovat onRestoreInstanceState(), což je systém volá po onStart()způsobu. Systém vyžaduje onRestoreInstanceState()pouze v případě, že je uložen stav obnovit, takže není třeba zkontrolovat, zda je Bundle je null:

  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(STATE_SCORE);
  mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
Odpovězeno 15/04/2016 v 04:13
zdroj uživatelem

hlasů
32

Opravdu onSaveInstancestav CALLEN když jde do pozadí aktivita

Citace z dokumentů: „metoda onSaveInstanceState(Bundle) se nazývá před umístěním činnost v takovém stavu, v pozadí“

Odpovězeno 23/05/2010 v 23:32
zdroj uživatelem

hlasů
28

Chcete-li pomoci snížit často používaný I použít následující interfacea classpro čtení / zápis na Bundlepro uložení instance stavu.


Za prvé, vytvoření rozhraní, které budou použity k anotaci své proměnné instance:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
        ElementType.FIELD
})
public @interface SaveInstance {

}

Pak vytvořte třídu, kde bude odraz slouží k uložení hodnot do svazku:

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

import java.io.Serializable;
import java.lang.reflect.Field;

/**
 * Save and load fields to/from a {@link Bundle}. All fields should be annotated with {@link
 * SaveInstance}.</p>
 */
public class Icicle {

    private static final String TAG = "Icicle";

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #load(Bundle, Object)
     */
    public static void save(Bundle outState, Object classInstance) {
        save(outState, classInstance, classInstance.getClass());
    }

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #load(Bundle, Object, Class)
     */
    public static void save(Bundle outState, Object classInstance, Class<?> baseClass) {
        if (outState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    field.setAccessible(true);
                    String key = className + "#" + field.getName();
                    try {
                        Object value = field.get(classInstance);
                        if (value instanceof Parcelable) {
                            outState.putParcelable(key, (Parcelable) value);
                        } else if (value instanceof Serializable) {
                            outState.putSerializable(key, (Serializable) value);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not added to the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #save(Bundle, Object)
     */
    public static void load(Bundle savedInstanceState, Object classInstance) {
        load(savedInstanceState, classInstance, classInstance.getClass());
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #save(Bundle, Object, Class)
     */
    public static void load(Bundle savedInstanceState, Object classInstance, Class<?> baseClass) {
        if (savedInstanceState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    String key = className + "#" + field.getName();
                    field.setAccessible(true);
                    try {
                        Object fieldVal = savedInstanceState.get(key);
                        if (fieldVal != null) {
                            field.set(classInstance, fieldVal);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not retrieved from the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

}

Příklad použití:

public class MainActivity extends Activity {

    @SaveInstance
    private String foo;

    @SaveInstance
    private int bar;

    @SaveInstance
    private Intent baz;

    @SaveInstance
    private boolean qux;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Icicle.load(savedInstanceState, this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Icicle.save(outState, this);
    }

}

Poznámka: Tento kód byl upraven z projektu knihovny s názvem AndroidAutowire který je licencován pod MIT licencí .

Odpovězeno 20/08/2015 v 02:04
zdroj uživatelem

hlasů
28

Zatím mám obecně ne více souvisejí s používáním

Bundle savedInstanceState & Co

živý cyklus je pro většinu činností příliš složité a není nutné. A Google uvádí sám, není to ani spolehlivé.

Moje cesta je okamžitě uložit změny v preferencích

 SharedPreferences p;
 p.edit().put(..).commit()

nějakým způsobem SharedPreferences fungovat podobný jako Svazky. A přirozeně i při prvních takových hodnot, musí být červené z preferencí.

V případě složitých dat můžete použít SQLite namísto použití předvoleb.

Při uplatňování tohoto pojmu je aktivita jen nadále používat poslední uložený stav, bez ohledu na to, zda se jedná o počáteční otevřené restartuje mezi nebo znovu kvůli zadním zásobníku.

Odpovězeno 31/03/2012 v 14:36
zdroj uživatelem

hlasů
25

Chcete-li odpovědět na původní otázku přímo. savedInstancestate je null, protože se nikdy stát se znovu vytvořila vaše aktivity.

Vaše aktivita bude znovu vytvořen pouze se státním svazku, když:

  • Změny konfigurace, jako je změna orientace nebo jazyka telefonu, který může vyžaduje novou instanci činnosti, která má být vytvořena.
  • Vrátíte se do aplikace na pozadí poté, co OS zničil aktivitu.

Android zničí činnosti na pozadí, když je pod tlakem paměti, nebo poté, co byly v pozadí po delší dobu.

Při testování Hello world příklad existuje několik způsobů, jak odejít a vrátit se k aktivitě.

  • Když stisknete tlačítko Zpět aktivita je dokončena. Opětovné spuštění aplikace je zcela nová instance. Nejste obnovení od pozadí vůbec.
  • Když stisknete tlačítko domů nebo použijte přepínač úloh aktivita půjde do pozadí. Při navigaci zpět do aplikace onCreate bude nazývat pouze v případě, pokud by činnosti, které mají být zničeny.

Ve většině případů, pokud jste pouhým stisknutím domů a potom spuštění aplikace opět aktivita nebudou muset být znovu vytvořen. Již v paměti existuje tak OnCreate () nebude být volán.

Je zde možnost v části Nastavení -> Možnosti pro vývojáře s názvem „Nenechávej činnosti“. Když je povolen Android bude vždy zničí činnost a znovu je, když jsou do pozadí. To je skvělá volba pro dovolenou povolen při vývoji, protože simuluje nejhorší možný scénář. (A low paměťové zařízení recyklace své aktivity po celou dobu).

Ostatní odpovědi jsou cenné v tom, že vás naučí správné způsoby ukládání stavu, ale neměl jsem pocit, že ve skutečnosti odpověděl, proč váš kód nefunguje tak, jak jste očekávali.

Odpovězeno 21/01/2015 v 02:19
zdroj uživatelem

hlasů
23

onSaveInstanceState(bundle)A onRestoreInstanceState(bundle)metody jsou užitečné pro datové persistence pouze při otáčení obrazovky (změna orientace).
Oni nejsou ani dobré, při přepínání mezi aplikacemi (protože onSaveInstanceState()metoda se nazývá, ale onCreate(bundle)i onRestoreInstanceState(bundle)není znovu vyvolán.
Pro další použití vytrvalost sdílených preferencí. Přečíst tento článek

Odpovězeno 05/09/2012 v 09:27
zdroj uživatelem

hlasů
15

Můj problém byl, že jsem potřeboval vytrvalost pouze během životnosti aplikace (tj jednom provedení, včetně spuštění další dílčí aktivity v rámci stejné aplikace a otáčení zařízení atd). Zkoušel jsem různé kombinace výše uvedených odpovědí, ale nedostal to, co jsem chtěl ve všech situacích. Na konci, co pracoval pro mě bylo získat odkaz na savedInstanceState během onCreate:

mySavedInstanceState=savedInstanceState;

a použít k získání obsahu mé proměnné, když jsem potřeboval to, v duchu:

if (mySavedInstanceState !=null) {
   boolean myVariable = mySavedInstanceState.getBoolean("MyVariable");
}

I používat onSaveInstanceStatea onRestoreInstanceStatejak je uvedeno výše, ale myslím, že bych mohl také, nebo alternativně použít můj způsob uložení proměnné, když se změní (například s využitím putBoolean)

Odpovězeno 16/04/2014 v 18:11
zdroj uživatelem

hlasů
12

I když je přijata odpověď je správná, je rychlejší a snadnější způsob, jak zachránit stát aktivity na Android pomocí knihovny s názvem Icepick . Icepick je anotace procesor, který se stará o veškerou často používaný kód použitý při záchraně a obnově stavu pro vás.

Dělá něco podobného s Icepick:

class MainActivity extends Activity {
  @State String username; // These will be automatically saved and restored
  @State String password;
  @State int age;

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

Je stejné jako to dělá:

class MainActivity extends Activity {
  String username;
  String password;
  int age;

  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putString("MyString", username);
    savedInstanceState.putString("MyPassword", password);
    savedInstanceState.putInt("MyAge", age); 
    /* remember you would need to actually initialize these variables before putting it in the
    Bundle */
  }

  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    username = savedInstanceState.getString("MyString");
    password = savedInstanceState.getString("MyPassword");
    age = savedInstanceState.getInt("MyAge");
  }
}

Icepick bude pracovat s libovolný objekt, který ukládá svůj stav s Bundle.

Odpovězeno 26/01/2016 v 03:07
zdroj uživatelem

hlasů
12

V zásadě existují dva způsoby, jak implementovat tuto změnu.

  1. s použitím onSaveInstanceState()a onRestoreInstanceState().
  2. V manifestu android:configChanges="orientation|screenSize".

Opravdu nedoporučuji používat druhý způsob. Vzhledem k tomu, v jedné z mých zkušeností to bylo příčinou polovina obrazovky černé zařízení při rotaci na výšku nebo na šířku a naopak.

Použitím první výše uvedené metody, můžeme přetrvávat data, když se orientace měnit nebo jakákoliv změna konfigurace se stane. Znám způsob, jakým si můžete ukládat jakýkoli druh dat uvnitř savedInstance stavu objektu.

Příklad: Uvažujme případ, chcete-li přetrvávat JSON objekt. vytvořit třídu modelu s získání a nastavení.

class MyModel extends Serializable{
JSONObject obj;

setJsonObject(JsonObject obj)
{
this.obj=obj;
}

JSONObject getJsonObject()
return this.obj;
} 
}

Nyní ve své činnosti v onCreate a onSaveInstanceState metody proveďte následující kroky. To bude vypadat nějak takto:

@override
onCreate(Bundle savedInstaceState){
MyModel data= (MyModel)savedInstaceState.getSerializable("yourkey")
JSONObject obj=data.getJsonObject();
//Here you have retained JSONObject and can use.
}


@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Obj is some json object 
MyModel dataToSave= new MyModel();
dataToSave.setJsonObject(obj);
oustate.putSerializable("yourkey",dataToSave); 

}
Odpovězeno 18/12/2015 v 11:43
zdroj uživatelem

hlasů
11

Když je vytvořena aktivita je OnCreate () metoda se nazývá.

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

savedInstanceState je objekt třídy ke svazku, který je nulový poprvé, ale obsahuje hodnoty, když je znovu vytvořit. Chcete-li ušetřit Aktivita je stav, budete muset přepsat onSaveInstanceState ().

   @Override
    protected void onSaveInstanceState(Bundle outState) {
      outState.putString("key","Welcome Back")
        super.onSaveInstanceState(outState);       //save state
    }

dát své hodnoty v "outState" Bundle objekt jako outState.putString ( "key", "Welcome Back") a uložit voláním Super. Když aktivita bude zničena to stát dostat uloženy v Bundle objektu a může být obnovena po rekreaci v onCreate () nebo onRestoreInstanceState (). Bundle obdržel v onCreate () a onRestoreInstanceState () jsou stejné.

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          //restore activity's state
         if(savedInstanceState!=null){
          String reStoredString=savedInstanceState.getString("key");
            }
    }

nebo

  //restores activity's saved state
 @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
      String restoredMessage=savedInstanceState.getString("key");
    }
Odpovězeno 23/01/2017 v 10:29
zdroj uživatelem

hlasů
8

Zde je komentář Steve Moseley je odpověď (o ToolmakerSteve ), který dává věci do souvislostí (v celém onSaveInstanceState vs onPause východně náklady vs západní nákladů sága)

@VVK - I částečně nesouhlasím. Některé způsoby ukončení aplikace nespouštějí onSaveInstanceState (OSIS). To omezuje užitečnost osis. Jeho stojí za podporu, neboť minimální OS zdrojů, ale v případě, že aplikace chce vrátit uživateli stavu, v jakém byly in, bez ohledu na to, jak se aplikace ukončen, je nezbytné, aby použil přetrvávající přístup skladování. Používám onCreate ke kontrole svazku, a pokud je to chybí, pak zkontrolujte trvalé úložiště. To centralizuje rozhodování. Mohu zotavit z havárie, nebo zadní exit tlačítka nebo vlastní položku menu Exit, nebo se vrátit k uživateli obrazovky byla na několik dní později. - ToolmakerSteve 19.září '15 v 10:38

Odpovězeno 07/02/2017 v 15:56
zdroj uživatelem

hlasů
7

Chcete-li získat státní Údaje o činnosti uložené v onCreate(), musíte nejprve uložit data v savedInstanceState naléhavým SaveInstanceState(Bundle savedInstanceState)způsobem.

Když aktivita zničit SaveInstanceState(Bundle savedInstanceState)metoda volána a tam uložit data, která chcete uložit. A dostanete stejné onCreate(), když restartu činnosti. (SavedInstanceState zvyklý být null, protože jste uložili některá data v něm před aktivitou dostat zničeny)

Odpovězeno 28/09/2016 v 11:46
zdroj uživatelem

hlasů
6

Není si jistý, jestli moje řešení je odsuzován, nebo ne, ale já používám vázaného službu přetrvávat viewmodel stavu. Ať se vám to uložit do paměti ve službě nebo přetrvávají a získávat z SqlLite databáze závisí na vašich požadavcích. To je to, co služby jakéhokoli chuť dělat, které poskytují služby, jako je udržení stavu aplikace a abstraktní společnou obchodní logiky.

Vzhledem k tomu, paměťových a zpracovatelských omezení vyplývajících na mobilních zařízeních, chovám Android pohledy v podobným způsobem na webové stránce. Stránka neudržuje stavu, to je čistě součástí prezentační vrstva, jehož jediným cílem je prezentovat stav aplikace a přijmout vstup od uživatele. Současné trendy v architektuře webové aplikace využívají používání věku starého modelu, View, Controller (MVC) vzoru, kde strana je View data Domain je model a řadič sedí za webové služby. Stejný vzor může být použit v android s názorem, že dobře ... View, model je vaše data domény a řadič je implementován jako vázaný službě Android. Kdykoliv budete chtít pohled komunikovat s regulátorem, se vážou k ní při startu / životopis a odpojení k zastavení / pauza.

Tento přístup vám dává bonus prosazení oddělení zodpovědností konstrukčního principu v tom, že všichni z vás aplikace obchodní logiky mohou být přesunuty do svého provozu, což snižuje duplicitní logiku napříč různými pohledy a umožňuje pohled prosadit další důležitý princip konstrukce, jediný zodpovědnost.

Odpovězeno 09/08/2016 v 12:57
zdroj uživatelem

hlasů
6

Jednoduchá rychlá, jak vyřešit tento problém je pomocí IcePick

Za prvé, nastavení knihovny v app/build.gradle

repositories {
  maven {url "https://clojars.org/repo/"}
}
dependencies {
  compile 'frankiesardo:icepick:3.2.0'
  provided 'frankiesardo:icepick-processor:3.2.0'
}

Nyní se pojďme zkontrolovat tento níže uvedený příklad, jak zachránit stát v aktivitě

public class ExampleActivity extends Activity {
  @State String username; // This will be automatically saved and restored

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

Pracuje pro činnosti, fragmenty nebo libovolný objekt, který potřebuje k serializaci svůj stav na Bundle (ViewPresenters např malta se)

Icepick může také generovat instance kód státu pro vlastní pohledy:

class CustomView extends View {
  @State int selectedPosition; // This will be automatically saved and restored

  @Override public Parcelable onSaveInstanceState() {
    return Icepick.saveInstanceState(this, super.onSaveInstanceState());
  }

  @Override public void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state));
  }

  // You can put the calls to Icepick into a BaseCustomView and inherit from it
  // All Views extending this CustomView automatically have state saved/restored
}
Odpovězeno 08/08/2016 v 02:07
zdroj uživatelem

hlasů
5

Kotlin kód:

Uložit:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState.apply {
        putInt("intKey", 1)
        putString("stringKey", "String Value")
        putParcelable("parcelableKey", parcelableObject)
    })
}

a pak v onCreate()neboonRestoreInstanceState()

    val restoredInt = savedInstanceState?.getInt("intKey") ?: 1 //default int
    val restoredString = savedInstanceState?.getString("stringKey") ?: "default string"
    val restoredParcelable = savedInstanceState?.getParcelable<ParcelableClass>("parcelableKey") ?: ParcelableClass() //default parcelable

Přidejte výchozí hodnoty, pokud nechcete mít Volitelně

Odpovězeno 12/02/2018 v 19:42
zdroj uživatelem

hlasů
0

Kotlin

Musíte přepsat onSaveInstanceStatea onRestoreInstanceStateuložit a načíst proměnné chcete být trvalá

Životní cyklus grafu

Uložení proměnné

public override fun onSaveInstanceState(savedInstanceState: Bundle) {
    super.onSaveInstanceState(savedInstanceState)

    // prepare variables here
    savedInstanceState.putInt("kInt", 10)
    savedInstanceState.putBoolean("kBool", true)
    savedInstanceState.putDouble("kDouble", 4.5)
    savedInstanceState.putString("kString", "Hello Kotlin")
}

načtení proměnných

public override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)

    val myInt = savedInstanceState.getInt("kInt")
    val myBoolean = savedInstanceState.getBoolean("kBool")
    val myDouble = savedInstanceState.getDouble("kDouble")
    val myString = savedInstanceState.getString("kString")
    // use variables here
}
Odpovězeno 01/06/2019 v 10:05
zdroj uživatelem

hlasů
0

Mám lepší nápad. To by bylo lepší ukládat data bez onCreate opět volá. Můžete ji vypnout z činnosti, pokud je orientace mění.

Ve svém manifestu:

<activity android:name=".MainActivity"
        android:configChanges="orientation|screenSize">
Odpovězeno 27/02/2019 v 10:12
zdroj uživatelem

hlasů
0

Co je třeba zachránit a co ne?

Přemýšleli jste někdy, proč text ve EditTextdostane automaticky uloží, když je změna orientace? No, tato odpověď je pro vás.

Když instancí činnosti zničena a systém znovu vytvoří novou instanci (například změnu konfigurace). Snaží se ji obnovit pomocí sady uložených dat starého státu aktivity ( instance státu ).

Instance stav je sbírka klíč-hodnota párů uložených v Bundleobjektu.

Ve výchozím nastavení systému ukládá-li zobrazit objekty ve svazku například.

  • text EditText
  • Posun pozice v ListView, atd.

Pokud budete potřebovat další proměnné, které mají být uloženy jako součást instance stavu, měli byste přepsat onSavedInstanceState(Bundle savedinstaneState) metodu.

Například, int currentScorev GameActivity

Více podrobností o onSavedInstanceState (Bundle savedinstaneState) při ukládání dat

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

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

Tak omylem, pokud jste zapomněl zavolat super.onSaveInstanceState(savedInstanceState);výchozí chování nebude fungovat, tj text EDITTEXT nezachrání.

Který si vybrat pro obnovení stavu aktivity?

 onCreate(Bundle savedInstanceState)

NEBO

onRestoreInstanceState(Bundle savedInstanceState)

Obě metody dostat stejné Bundle objekt, takže to není opravdu jedno, kam napsat svůj vratný logiku. Jediným rozdílem je, že v onCreate(Bundle savedInstanceState)metodě budete muset dát šek null, když to není potřeba ve druhém případě. Jiné odpovědi již kousky kódu. Můžete je položit.

Více podrobností o onRestoreInstanceState (Bundle savedinstaneState)

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

    // Restore state members from the saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}

Vždy volejte super.onRestoreInstanceState(savedInstanceState);takže systém lze obnovit pohled hierarchii implicitně

prémie

onSaveInstanceState(Bundle savedInstanceState)Je vyvolán systémem pouze tehdy, když uživatel má v úmyslu vrátit se do aktivity. Například používáte App X a najednou dostanete hovoru. Přesunete do aplikace volajícího a vrátit se do aplikace X. V tomto případě onSaveInstanceState(Bundle savedInstanceState)metoda bude vyvolána.

Ale za to v případě, že uživatel stiskne tlačítko Zpět. Předpokládá se, že uživatel nemá v úmyslu vrátit se do činnosti, a proto v tomto případě onSaveInstanceState(Bundle savedInstanceState)nebude vyvolána systémem. Bod je, měli byste zvážit všechny scénáře při ukládání dat.

Relevantní odkazy:

Demo na výchozí chování
Android úřední dokumentace .

Odpovězeno 10/01/2019 v 08:48
zdroj uživatelem

hlasů
0

Nyní Android poskytuje ViewModels pro ukládání stavu, měli byste se pokusit použít, že místo saveInstanceState.

Odpovězeno 27/08/2018 v 11:51
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more