android-activity सहेजें इंस्टेंस स्टेट का उपयोग करके Android गतिविधि स्थिति सहेजना





13 Answers

सहेजे गए इंस्टेंसस्टेट केवल गतिविधि के वर्तमान उदाहरण से जुड़े राज्य को सहेजने के लिए है, उदाहरण के लिए वर्तमान नेविगेशन या चयन जानकारी, ताकि अगर एंड्रॉइड किसी गतिविधि को नष्ट कर देता है और पुन: प्रयास करता है, तो यह पहले जैसा था, उतना वापस आ सकता है। onSaveInstanceState और onSaveInstanceState लिए प्रलेखन देखें

अधिक लंबे समय तक रहने वाले राज्य के लिए, SQLite डेटाबेस, फ़ाइल या प्राथमिकताओं का उपयोग करने पर विचार करें। सेविंग पर्सिस्टेंट स्टेट देखें।

android android-activity application-state

मैं एंड्रॉइड एसडीके मंच पर काम कर रहा हूं, और यह थोड़ा अस्पष्ट है कि एप्लिकेशन के राज्य को कैसे सहेजना है। इसलिए 'हैलो, एंड्रॉइड' उदाहरण के इस मामूली पुन: टूलिंग को दिया गया:

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);
  }
}

मैंने सोचा कि यह सबसे आसान मामले के लिए पर्याप्त होगा, लेकिन यह हमेशा पहले संदेश के साथ प्रतिक्रिया करता है, इससे कोई फर्क नहीं पड़ता कि मैं ऐप से कैसे नेविगेट करता हूं।

मुझे यकीन है कि समाधान ओवरराइडिंग के समान सरल है या ऐसा कुछ है, लेकिन मैं 30 मिनट या उससे अधिक के लिए प्रलेखन में दूर हो रहा हूं और कुछ भी स्पष्ट नहीं मिला है।




मेरे सहयोगी ने एंड्रॉइड उपकरणों पर एप्लिकेशन स्टेट को समझाते हुए एक लेख लिखा जिसमें गतिविधि लाइफसाइक्ल और राज्य सूचना, राज्य जानकारी कैसे स्टोर करें, और राज्य Bundle और SharedPreferences और यहां पर एक नज़र SharedPreferences सहित स्पष्टीकरण शामिल हैं

लेख में तीन दृष्टिकोण शामिल हैं:

इंस्टेंस स्टेट बंडल का उपयोग करके एप्लिकेशन जीवनकाल (यानी अस्थायी रूप से) के लिए स्थानीय वैरिएबल / यूआई नियंत्रण डेटा स्टोर करें

[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);
}

साझा प्राथमिकताओं का उपयोग कर अनुप्रयोग उदाहरणों (यानी स्थायी रूप से) के बीच स्थानीय वैरिएबल / यूआई नियंत्रण डेटा स्टोर करें

[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();
}

बनाए गए गैर-कॉन्फ़िगरेशन इंस्टेंस का उपयोग करके एप्लिकेशन जीवनकाल में गतिविधियों के बीच स्मृति में ऑब्जेक्ट उदाहरणों को जीवित रखना

[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();
}



onSaveInstanceState को तब कहा जाता है जब सिस्टम को स्मृति की आवश्यकता होती है और एप्लिकेशन को मार देता है। यह तब नहीं कहा जाता जब उपयोगकर्ता सिर्फ एप्लिकेशन को बंद कर देता है। तो मुझे लगता है कि आवेदन स्थिति को भी सहेजना चाहिए क्योंकि इसे कुछ निरंतर भंडारण जैसे Preferences या Sqlite सहेजा जाना चाहिए




जहां तक ​​मेरा संबंध है, राज्य को सहेजना सबसे अच्छा है। यदि आपको लगातार डेटा को सहेजने की आवश्यकता है, तो बस एक SQLite डेटाबेस का उपयोग करें। एंड्रॉइड इसे सूओ आसान बनाता है।

कुछ इस तरह:

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 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) {
        }
    }
}

उसके बाद एक साधारण कॉल

dataHelper dh = new dataHelper(getBaseContext());
String status = (String) dh.getCode("appState", "safetyDisabled");
Date serviceStart = (Date) dh.getCode("serviceStartTime", null);
dh.close();
dh = null;



एक गतिविधि को दोबारा बनाना

ऐसे कुछ परिदृश्य हैं जिनमें सामान्य ऐप व्यवहार के कारण आपकी गतिविधि नष्ट हो जाती है, जैसे कि जब उपयोगकर्ता बैक बटन दबाता है या आपकी गतिविधि finish() को कॉल करके अपना विनाश सिग्नल करती है। सिस्टम वर्तमान में बंद होने पर भी आपकी गतिविधि को नष्ट कर सकता है और लंबे समय तक उपयोग नहीं किया गया है या अग्रभूमि गतिविधि को अधिक संसाधनों की आवश्यकता है ताकि सिस्टम को स्मृति पुनर्प्राप्ति के लिए पृष्ठभूमि प्रक्रियाओं को बंद कर देना चाहिए।

जब आपकी activity नष्ट हो जाती है क्योंकि उपयोगकर्ता वापस दबाता है या activity स्वयं समाप्त होती है, तो उस Activity के सिस्टम की अवधारणा हमेशा के लिए चली जाती है क्योंकि व्यवहार इंगित करता है कि गतिविधि की अब आवश्यकता नहीं है। हालांकि, अगर सिस्टम सिस्टम की बाधाओं (सामान्य ऐप व्यवहार के बजाए) गतिविधि के कारण गतिविधि को नष्ट कर देता है, तो वास्तविक गतिविधि उदाहरण समाप्त हो गया है, तो सिस्टम को याद है कि यह अस्तित्व में है कि यदि उपयोगकर्ता इसे वापस नेविगेट करता है, तो सिस्टम एक नया बनाता है सहेजे गए डेटा के एक सेट का उपयोग करके गतिविधि का उदाहरण जो गतिविधि की स्थिति को destroyed होने पर वर्णित करता है। पिछले राज्य को पुनर्स्थापित करने के लिए सिस्टम द्वारा सहेजे गए सहेजे गए डेटा को "इंस्टेंस स्टेटस" कहा जाता है और यह बंडल ऑब्जेक्ट में संग्रहीत कुंजी-मूल्य जोड़े का संग्रह होता है।

गतिविधि स्थिति के बारे में अतिरिक्त डेटा सहेजने के लिए, आपको ऑनसेवस्टेंसस्टेट () कॉलबैक विधि को ओवरराइड करना होगा। सिस्टम इस विधि को कॉल करता है जब उपयोगकर्ता आपकी गतिविधि छोड़ रहा है और उसे बंडल ऑब्जेक्ट पास करता है जो उस घटना में सहेजा जाएगा जब आपकी गतिविधि अप्रत्याशित रूप से नष्ट हो जाती है। यदि सिस्टम को बाद में गतिविधि उदाहरण को फिर से बनाना चाहिए, तो यह उसी बंडल ऑब्जेक्ट को onRestoreInstanceState() और onRestoreInstanceState() onCreate() विधियों दोनों पर onRestoreInstanceState()

चूंकि सिस्टम आपकी गतिविधि को रोकने के लिए शुरू होता है, यह onSaveInstanceState() (1) पर कॉल onSaveInstanceState() ताकि आप गतिविधि स्थिति को पुनर्निर्मित करने के मामले में अतिरिक्त राज्य डेटा निर्दिष्ट कर सकें जिसे आप सहेजना चाहते हैं। यदि गतिविधि नष्ट हो जाती है और एक ही उदाहरण को फिर से बनाया जाना चाहिए, तो सिस्टम (1) पर परिभाषित राज्य डेटा को onRestoreInstanceState() विधि (2) और onRestoreInstanceState() विधि (3) दोनों में पास करता है।

अपना Activity राज्य बचाओ

चूंकि आपकी गतिविधि रुकने लगती है, सिस्टम onSaveInstanceState() कॉल करता है, इसलिए आपकी गतिविधि कुंजी-मूल्य जोड़े के संग्रह के साथ राज्य की जानकारी को सहेज सकती है। इस विधि का डिफ़ॉल्ट कार्यान्वयन गतिविधि के दृश्य पदानुक्रम की स्थिति के बारे में जानकारी सहेजता है, जैसे किसी EditText टेक्स्ट विजेट में टेक्स्ट या ListView की स्क्रॉल स्थिति।

अपनी गतिविधि के लिए अतिरिक्त राज्य जानकारी को सहेजने के लिए, आपको onSaveInstanceState() लागू करना होगा और बंडल ऑब्जेक्ट में कुंजी-मूल्य जोड़े जोड़ना होगा। उदाहरण के लिए:

  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);
}

सावधानी: हमेशा onSaveInstanceState() के onSaveInstanceState() कार्यान्वयन को कॉल करें ताकि डिफ़ॉल्ट कार्यान्वयन दृश्य पदानुक्रम की स्थिति को बचा सके।

अपने Activity राज्य को पुनर्स्थापित करें

जब आपकी गतिविधि को पहले नष्ट कर दिया गया था, तो आप अपनी सहेजी गई स्थिति को बंडल से पुनर्प्राप्त कर सकते हैं कि सिस्टम आपकी गतिविधि को पास करता है। onCreate() और onRestoreInstanceState() कॉलबैक विधियों दोनों एक ही Bundle प्राप्त करते हैं जिसमें इंस्टेंस onRestoreInstanceState() जानकारी होती है।

चूंकि onCreate() विधि को कॉल किया जाता है कि क्या सिस्टम आपकी गतिविधि का एक नया उदाहरण बना रहा है या पिछले एक को पुनर्निर्माण कर रहा है, आपको यह जांचना होगा कि क्या आप इसे पढ़ने का प्रयास करने से पहले राज्य बंडल शून्य है या नहीं। यदि यह शून्य है, तो सिस्टम नष्ट हो गया था जो पिछले एक को बहाल करने के बजाय, गतिविधि का एक नया उदाहरण बना रहा है।

उदाहरण के लिए, यहां पर कुछ राज्य डेटा को कैसे 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
 }

 }

onRestoreInstanceState() दौरान राज्य को बहाल करने के बजाय आप onStart() विधि के बाद सिस्टम को कॉल करने के लिए onStart() पर लागू करना चुन सकते हैं। सिस्टम onRestoreInstanceState() कॉल onRestoreInstanceState() यदि पुनर्स्थापित करने के लिए कोई सहेजा गया राज्य है, तो आपको यह जांचने की आवश्यकता नहीं है कि बंडल शून्य है या नहीं:

  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);
}



onSaveInstanceजब गतिविधि पृष्ठभूमि में जाती है तो वास्तव में राज्य कॉलन

दस्तावेज़ों से उद्धरण: "इस onSaveInstanceState(Bundle)तरह की पृष्ठभूमि स्थिति में गतिविधि रखने से पहले विधि को बुलाया जाता है"




बॉयलरप्लेट को कम करने में मदद के लिए मैं निम्नलिखित का उपयोग करता हूं interfaceऔर उदाहरण स्थिति को सहेजने के लिए classपढ़ने / लिखने के लिए Bundle

सबसे पहले, एक इंटरफ़ेस बनाएं जिसका उपयोग आपके इंस्टेंस चर को एनोटेट करने के लिए किया जाएगा:

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 {

}

फिर, एक वर्ग बनाएं जहां प्रतिबिंब का उपयोग बंडल को मूल्यों को सहेजने के लिए किया जाएगा:

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();
        }
    }

}

उदाहरण का उपयोग:

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);
    }

}

नोट: यह कोड AndroidAutowire नामक लाइब्रेरी प्रोजेक्ट से अनुकूलित किया गया था जिसे एमआईटी लाइसेंस के तहत लाइसेंस प्राप्त है ।




onSaveInstanceState(bundle)और onRestoreInstanceState(bundle)तरीकों डेटा हठ स्क्रीन (उन्मुखीकरण परिवर्तन) घूर्णन केवल थोड़ी देर के लिए उपयोगी होते हैं।
वे अनुप्रयोगों के बीच स्विच (के बाद से, जबकि भी अच्छा नहीं कर रहे हैं onSaveInstanceState()विधि कहा जाता है लेकिन onCreate(bundle)और onRestoreInstanceState(bundle)फिर से लागू नहीं है।
अधिक दृढ़ता उपयोग साझा वरीयताओं के लिए। यह लेख पढ़ें




यद्यपि स्वीकार्य उत्तर सही है, लेकिन Icepick पर गतिविधि स्थिति को 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);
  }
}

ऐसा करने जैसा ही है:

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");
  }
}

आइसपिक किसी भी ऑब्जेक्ट के साथ काम करेगा जो इसके साथ एक राज्य को बचाता है Bundle




जब कोई गतिविधि बनाई जाती है तो यह क्रिएट () विधि को कॉल किया जाता है।

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

savedInstanceState बंडल क्लास का एक ऑब्जेक्ट है जो पहली बार शून्य है, लेकिन इसमें इसे पुनर्निर्मित होने पर मान शामिल हैं। गतिविधि की स्थिति को सहेजने के लिए आपको SaveInstanceState () पर ओवरराइड करना होगा।

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

अपने मूल्यों को "आउटस्टेट" बंडल ऑब्जेक्ट में आउटस्टेट.पुटस्ट्रिंग ("कुंजी", "वेलकम बैक") में रखें और सुपर कॉल करके सहेजें। जब गतिविधि नष्ट हो जाएगी, तो यह राज्य बंडल ऑब्जेक्ट में सहेजा जाएगा और इसे क्रेते () या ऑनस्टोर इंस्टेंसस्टेट () पर मनोरंजन के बाद बहाल किया जा सकता है। क्रेट () और ऑनस्टोर इंस्टेंसस्टेट () पर प्राप्त बंडल समान हैं।

   @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");
            }
    }

या

  //restores activity's saved state
 @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
      String restoredMessage=savedInstanceState.getString("key");
    }



कोटलिन कोड:

बचाना:

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

और फिर में onCreate()याonRestoreInstanceState()

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

यदि आप विकल्प नहीं चाहते हैं तो डिफ़ॉल्ट मान जोड़ें




इस समस्या को हल करने के लिए सरल त्वरित Icepick का उपयोग कर Icepick

सबसे पहले, पुस्तकालय में सेटअप करें app/build.gradle

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

अब, गतिविधि में राज्य को कैसे सहेजना है, इस उदाहरण को नीचे देखें

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);
  }
}

यह क्रियाकलापों, टुकड़ों या किसी ऑब्जेक्ट के लिए काम करता है जिसे बंडल पर अपने राज्य को क्रमबद्ध करने की आवश्यकता होती है (उदाहरण के लिए मोर्टार के व्यूपेंटर)

आइसपिक कस्टम दृश्यों के लिए इंस्टेंस स्टेट कोड भी उत्पन्न कर सकता है:

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
}



अब एंड्रॉइड राज्य को सहेजने के लिए ViewModels प्रदान करता है , आपको इसेInstanceState को सहेजने के बजाय उपयोग करने का प्रयास करना चाहिए।






Related