android-activity onsaveinstancestate 호출시점 - 인스턴스 상태 저장을 사용하여 Android 액티비티 상태 저장하기




13 Answers

savedInstanceState 는 활동의 현재 인스턴스 (예 : 현재 탐색 또는 선택 정보)와 연관된 상태를 저장하기위한 savedInstanceState 뿐이므로 Android가 활동을 파괴하고 다시 작성하면 이전 상태로 돌아갈 수 있습니다. onCreateonSaveInstanceState 대한 설명서를 참조하십시오.

수명이 긴 상태를 유지하려면 SQLite 데이터베이스, 파일 또는 환경 설정 사용을 고려하십시오. 영구 상태 저장을 참조하십시오.

안드로이드 recreate onrestoreinstancestate

Android SDK 플랫폼에서 작업 해 왔으며 애플리케이션 상태를 저장하는 방법이 약간 명확하지 않습니다. 그래서 'Hello, Android'예제를 약간 수정하면 다음과 같습니다.

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

가장 단순한 경우에는 충분하다고 생각했지만, 앱에서 어떻게 벗어나도 첫 번째 메시지로 항상 응답합니다.

나는 해결책이 onPause 를 무시하는 것처럼 간단하다고 확신한다. 그러나 나는 30 분 정도의 문서에서 벗어나 뻔한 것을 발견하지 못했다.




동료는 활동주기 및 상태 정보, 상태 정보 저장 방법, State BundleSharedPreferences 저장 방법과 같은 Android 장치의 응용 프로그램 상태를 설명하는 기사를 작성하여 여기에서 살펴보십시오 .

이 기사에서는 세 가지 방법을 다룹니다.

Instance State Bundle을 사용하여 응용 프로그램 수명 (즉, 일시적으로)에 대한 로컬 가변 / UI 제어 데이터 저장

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

공유 환경 설정을 사용하여 응용 프로그램 인스턴스간에 영구적으로 로컬 변수 / UI 제어 데이터 저장

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

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



onSaveInstanceState 는 시스템이 메모리를 필요로하고 응용 프로그램을 종료 할 때 호출됩니다. 사용자가 응용 프로그램을 닫을 때 호출되지 않습니다. 그래서 응용 프로그램 상태도 onPause 저장해야한다고 생각합니다. Preferences 또는 Sqlite 와 같은 일부 영구 저장소에 저장해야합니다.




저축 상태는 내가 아는 한 최선을 다합니다. 영구 데이터를 저장해야하는 경우 SQLite 데이터베이스 만 사용하면됩니다. Android는 SOOO를 쉽게 만듭니다.

이 같은:

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 인스턴스가 더 이상 활동이 필요하지 않음을 나타내므로 Activity 인스턴스의 시스템 개념은 영원히 사라집니다. 그러나 시스템이 정상적인 응용 프로그램 동작이 아닌 시스템 제약으로 인해 활동을 파괴하면 실제 Activity 인스턴스가 사라지더라도 시스템은 사용자가 다시 탐색하면 시스템이 새로운 Activity 인스턴스를 만듭니다 활동이 destroyed 되었을 때의 활동 상태를 설명하는 저장된 데이터 세트를 사용하여 활동의 인스턴스. 시스템이 이전 상태를 복원하는 데 사용하는 저장된 데이터를 "인스턴스 상태"라고하며 Bundle 객체에 저장된 키 - 값 쌍의 모음입니다.

활동 상태에 대한 추가 데이터를 저장하려면 onSaveInstanceState () 콜백 메서드를 재정의해야합니다. 사용자가 활동을 떠날 때 시스템에서이 메소드를 호출하고 예기치 않게 활동이 손상된 경우에 저장 될 Bundle 오브젝트를 전달합니다. 시스템이 나중에 활동 인스턴스를 재 작성해야하는 경우, 동일한 Bundle 오브젝트를 onRestoreInstanceState()onCreate() 메소드 모두에 전달합니다.

시스템에서 활동을 중지하기 시작하면 onSaveInstanceState() (1)가 호출되므로 Activity 인스턴스를 다시 작성해야 할 경우에 대비하여 저장할 상태 데이터를 추가로 지정할 수 있습니다. 활동이 삭제되고 동일한 인스턴스를 다시 작성해야하는 경우 시스템은 (1)에서 정의 된 상태 데이터를 onCreate() 메소드 (2)와 onRestoreInstanceState() 메소드 (3)에 전달합니다.

Activity 상태 저장

활동이 중지되기 시작할 때 시스템은 onSaveInstanceState() 호출하여 활동이 키 - 값 쌍의 콜렉션으로 상태 정보를 저장할 수있게합니다. 이 메소드의 기본 구현은 EditText 위젯의 텍스트 또는 ListView 의 스크롤 위치와 같은 활동의 뷰 계층 구조 상태에 대한 정보를 저장합니다.

활동에 대한 추가 상태 정보를 저장하려면 onSaveInstanceState() 구현하고 키 - 값 쌍을 Bundle 객체에 추가해야합니다. 예 :

  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() 의 수퍼 클래스 구현을 항상 호출하십시오.

Activity 상태 복원

이전에 파기 된 활동을 재 작성하면 시스템이 활동을 전달한 번들에서 저장된 상태를 복구 할 수 있습니다. onCreate()onRestoreInstanceState() 콜백 메서드는 모두 인스턴스 상태 정보가 들어있는 동일한 Bundle 을받습니다.

onCreate() 메서드는 시스템에서 활동의 새 인스턴스를 만들거나 이전 활동을 다시 만들 때 호출되므로 상태 묶음이 읽으려고 시도하기 전에 null인지 확인해야합니다. 그것이 널이면, 시스템은 이전에 파기 된 것을 복원하는 대신에 활동의 새 인스턴스를 작성 중입니다.

예를 들어 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
 }

 }

onCreate() 중 상태를 복원하는 대신 onRestoreInstanceState() 를 구현하도록 선택할 수 있습니다.이 메서드는 onStart() 메서드 이후에 시스템이 호출합니다. 복원 할 저장 상태가있는 경우에만 onRestoreInstanceState() 호출되므로 번들이 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);
}



Activity가 백그라운드로 이동하면 실제로 onSaveInstance 상태 onSaveInstance

문서에서 인용 : " onSaveInstanceState(Bundle) 메서드는 이러한 백그라운드 상태에 활동을 배치하기 전에 호출됩니다."




다음 내가 사용하는 보일러를 줄일 수 있도록 interface하고 classA를 읽기 / 쓰기로 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);
    }

}

참고 : 이 코드는 MIT 라이센스에 따라 라이센스가 부여 된 AndroidAutowire 라는 라이브러리 프로젝트에서 채택되었습니다 .




onSaveInstanceState(bundle)onRestoreInstanceState(bundle)메서드는 화면을 회전하는 동안 (오리 엔테이션 변경) 데이터 지속성에 유용합니다.
그들은 이후 (응용 프로그램 사이를 전환하는 동안도 잘되지 않습니다 onSaveInstanceState()메서드가 호출 되나 onCreate(bundle)하고 onRestoreInstanceState(bundle)다시 호출되지 않습니다.
더 지속성 사용 공유 설정하십시오. 이 기사를 읽고




받아 들여진 답이 맞지만, Icepick 이라는 라이브러리를 사용하여 Android에 활동 상태를 저장하는 더 빠르고 쉬운 방법이 있습니다. 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");
  }
}

Icepick은 a로 상태를 저장하는 객체와 함께 작동합니다 Bundle.




액티비티가 생성되면 onCreate () 메서드가 호출됩니다.

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

savedInstanceState는 처음에는 null 인 Bundle 클래스의 객체이지만 다시 만들 때 값을 포함합니다. Activity의 상태를 저장하려면 onSaveInstanceState ()를 재정의해야합니다.

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

outState.putString ( "key", "Welcome Back")과 같은 번들 객체를 "outState"에 넣고 super를 호출하여 저장하십시오. 활동이 파괴 될 때 상태는 Bundle 오브젝트에 저장되며 onCreate () 또는 onRestoreInstanceState ()에서 레크리에이션 후에 복원 될 수 있습니다. onCreate () 및 onRestoreInstanceState ()에서받은 번들은 동일합니다.

   @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

당신이 Optionals을 원하지 않으면 기본값을 추가하십시오.




Icepick 사용 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'
}

이제 Activity에 상태를 저장하는 방법을 아래의 예제에서 확인해 보겠습니다.

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

액티비티, 프래그먼트 또는 번들 (예 : 박격포의 ViewPresenters)에서 상태를 직렬화해야하는 모든 객체에 대해 작동합니다.

Icepick은 또한 사용자 정의보기에 대한 인스턴스 상태 코드를 생성 할 수 있습니다.

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 을 제공 하므로 saveInstanceState 대신에 그것을 사용하려고 시도해야합니다.




Related