onSaveInstanceState () 및 onRestoreInstanceState ()


138

내가 저장하고의 상태를 복원하기 위해 노력하고있어 Activity방법을 사용을 onSaveInstanceState()하고 onRestoreInstanceState().

문제는 onRestoreInstanceState()메소드에 절대 들어 가지 않는다는 것입니다. 왜 이것이 나에게 설명 할 수 있습니까?


1
@Nitin : 링크를 공유 주셔서 감사합니다 ...이 나를 위해 일 몇 가지를 정리했다
Taliadon

2
@NitinBansal 링크가 죽었습니다.
ashishdhiman2007

답변:


191

일반적으로에서 상태를 복원합니다 onCreate(). 복원도 가능 onRestoreInstanceState()하지만 일반적이지 않습니다. ( onRestoreInstanceState()이후 onStart()에 호출 되는 반면 onCreate()에 , 전에 호출 됨) onStart().

put 메소드를 사용하여 다음에 값을 저장하십시오 onSaveInstanceState().

protected void onSaveInstanceState(Bundle icicle) {
  super.onSaveInstanceState(icicle);
  icicle.putLong("param", value);
}

그리고 다음 값을 복원하십시오 onCreate().

public void onCreate(Bundle icicle) {
  if (icicle != null){
    value = icicle.getLong("param");
  }
}

2
문제는 startActivity를 사용하여 활동 A로 돌아가는 것입니다. 활동 B로 돌아갈 때 객체는 널 고드름입니다.
BlaBRA

5
내가 올바르게 이해하면 이것이 당신이하는 일입니다 : B에서 startActivity (A)를 호출합니다. 그런 다음 A에서 finish ()를 호출하여 B로 돌아갑니다. 이 경우 첫 번째 활동에서 B는 삭제되지 않았으며 onCreate () 또는 onRestoreInstanceState ()가 호출되지 않습니다. 이러한 메소드는 필요할 때, 즉 활동이 파괴되어 시스템에 의해 다시 작성되어야 할 때에 만 호출됩니다.
Robert

4
메모리 부족으로 인해 첫 번째 활동 B가 손상 될 수 있다고 덧붙여 야합니다. 이것은 onCreate 및 onRestoreInstanceState를 트리거합니다.
Robert

1
erikb, 예, 활동 B가 재개되거나 OS가 재개 한 후 재 작성한 후 재개합니다.
Robert


149

onRestoreInstanceState()라고 다시 때만 이 후 활동을 살해 OS에 의해. 이러한 상황은 다음과 같은 경우에 발생합니다.

  • 장치의 방향이 바뀝니다 (활동이 파괴되고 재 생성됨).
  • 당신 앞에 또 다른 활동이 있으며 어떤 시점에서 OS는 메모리를 확보하기 위해 활동을 종료합니다 (예 :). 다음에 활동을 시작하면 onRestoreInstanceState ()가 호출됩니다.

대조적으로 : 활동 중이고 Back장치의 버튼을 누르면 활동이 완료되고 (즉, 데스크탑 응용 프로그램을 종료하는 것으로 생각) 다음에 응용 프로그램을 시작할 때 "새로"시작됩니다. 당신이 때렸을 때 의도적으로 종료했기 때문에 저장된 상태 Back.

다른 혼란의 원인은 앱 onSaveInstanceState()이 다른 앱에 대한 포커스를 잃을 때 호출되지만 앱 으로 다시 탐색하면 onRestoreInstanceState()호출되지 않을 수 있다는 것입니다. 이것은 원래의 질문에 설명 된 경우입니다. 즉, 다른 활동이 시작된 기간 동안 활동이 종료되지 않은 경우 onRestoreInstanceState()활동이 거의 "활성"이기 때문에 호출되지 않습니다.

에 대한 문서에 명시된 바와 같이 onRestoreInstanceState():

대부분의 구현은 단순히 onCreate (Bundle)를 사용하여 상태를 복원하지만 모든 초기화가 완료된 후 여기에서 수행하거나 하위 클래스가 기본 구현을 사용할지 여부를 결정하도록하는 것이 편리한 경우가 있습니다. 이 메소드의 기본 구현은 onSaveInstanceState (Bundle)에 의해 이전에 정지 된 모든 뷰 상태의 복원을 수행합니다.

내가 읽은대로 : onRestoreInstanceState()서브 클래스를 작성하지 않고 Activity누군가가 서브 클래스를 서브 클래스 화 할 것으로 예상 되지 않는 한 재정의 할 이유가 없습니다 .


3
그렇습니다. 이것은 옳은 것 같습니다. imo 다른 액티비티에서 액티비티로 돌아올 때도 실행해야합니다. 필요한 상황이 많이 있습니다.
masi

4
@masi는 사용자가 다른 활동에서 반환 할 때 이미 다른 메소드가 호출되었습니다. onSave / RestoreInstanceState ()는 다른 특정 목적으로 사용됩니다.
superjos November

8

저장 한 상태 onSaveInstanceState()는 나중에 onCreate()메소드 호출시 사용 가능 합니다. 따라서 onCreate(및 해당 Bundle매개 변수)를 사용 하여 활동 상태를 복원하십시오.


4

임시 해결책으로 활동 A를 시작하는 데 사용하려는 의도로 유지하려는 데이터가있는 번들을 저장할 수 있습니다.

Intent intent = new Intent(this, ActivityA.class);
intent.putExtra("bundle", theBundledData);
startActivity(intent);

활동 A는 이것을 활동 B로 다시 전달해야합니다. 활동 B의 onCreate 메소드에서 의도를 검색합니다.

Intent intent = getIntent();
Bundle intentBundle;
if (intent != null)
    intentBundle = intent.getBundleExtra("bundle");
// Do something with the data.

또 다른 아이디어는 활동 상태를 저장하기 위해 저장소 클래스를 작성하고 각 활동이 해당 클래스를 참조하도록하는 것입니다 (단일 구조를 사용할 수 있음). 그러나 그렇게하는 것이 가치가있는 것보다 더 어려울 수 있습니다.


3

중요한 것은 당신이 저장하지 않는 경우이다 onSaveInstanceState()onRestoreInstanceState()호출되지 않습니다. 이것의 주된 차이점이다 restoreInstanceState()하고 onCreate(). 실제로 무언가를 보관하십시오. 아마도 이것이 당신의 문제입니다.


1
OnSaveInstanceState ()에 아무것도 저장하지 않아도 onRestoreInstanceState ()가 호출됩니다.
abh22ishek

3

다른 활동이 포 그라운드로 올 때 onSaveInstanceState가 항상 호출된다는 것을 알았습니다. 그리고 onStop입니다.

그러나 onCreate 및 onStart가 호출 된 경우에만 onRestoreInstanceState가 호출되었습니다. 그리고 onCreate 및 onStart가 항상 호출 된 것은 아닙니다.

따라서 활동이 백그라운드로 이동하더라도 Android가 항상 상태 정보를 삭제하지는 않는 것 같습니다. 그러나 라이프 사이클 메소드를 호출하여 상태를 안전하게 저장합니다. 따라서 상태가 삭제되지 않으면 Android는 수명주기 메소드를 호출하여 필요하지 않은 상태를 복원하지 않습니다.

그림 2 는이를 설명합니다.


2

이 스레드는 꽤 오래되었다고 생각합니다. onSaveInstanceState()전화를 거는 경우라고도 하는 다른 사례를 언급 합니다 Activity.moveTaskToBack(boolean nonRootActivity).


1

당신이 활동의 방향 변경을 처리하는 경우 android:configChanges="orientation|screenSize"onConfigurationChanged(Configuration newConfig), onRestoreInstanceState()호출되지 않습니다.


1

onRestoreInstanceState가 항상 onSaveInstanceState 다음에 호출 될 필요는 없습니다.

참고 : 활동이 회전 될 때 (방향이 처리되지 않을 때) onRestoreInstanceState가 항상 호출되거나 활동을 연 다음 다른 응용 프로그램을 열어 활동 인스턴스가 OS에 의해 메모리에서 지워집니다.


1

저장된 인스턴스 상태를 사용하여 활동 UI 상태 복원 문서에서 다음과 같이 표시됩니다.

onCreate () 동안 상태를 복원하는 대신 시스템이 onStart () 메소드 다음에 호출하는 onRestoreInstanceState ()를 구현하도록 선택할 수 있습니다. 시스템은 복원 할 저장된 상태가있는 경우에만 onRestoreInstanceState ()를 호출 하므로 번들이 널 인지 여부를 확인할 필요가 없습니다 .

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

IMO, 이것은 onCreate에서 이것을 확인하는 것보다 더 분명한 방법이며 단일 책임 원칙에 더 잘 맞습니다.


0

제 경우 onRestoreInstanceState에는 장치 방향을 변경 한 후 활동을 재구성 할 때 호출되었습니다. onCreate(Bundle)이 (가) 먼저 호출되었지만 번들에 내가 설정 한 키 / 값이 없습니다 onSaveInstanceState(Bundle).

바로 다음에 onRestoreInstanceState(Bundle)올바른 키 / 값이있는 번들로 호출되었습니다.



0

나는 그렇게 할 수있다 (미안하지만 C #은 아니지만 문제는 아니다 ...) :

private int iValue = 1234567890;

function void MyTest()
{
    Intent oIntent = new Intent (this, typeof(Camera2Activity));
    Bundle oBundle = new Bundle();
    oBundle.PutInt("MYVALUE", iValue); //=> 1234567890
    oIntent.PutExtras (oBundle);
    iRequestCode = 1111;
    StartActivityForResult (oIntent, 1111);
}

그리고 당신의 결과에 대한 활동

private int iValue = 0;

protected override void OnCreate(Bundle bundle)
{
    Bundle oBundle =  Intent.Extras;
    if (oBundle != null)
    {
        iValue = oBundle.GetInt("MYVALUE", 0);
        //=>1234567890
    }
}

private void FinishActivity(bool bResult)
{
    Intent oIntent = new Intent();
    Bundle oBundle = new Bundle();
    oBundle.PutInt("MYVALUE", iValue);//=>1234567890
    oIntent.PutExtras(oBundle);
    if (bResult)
        {
            SetResult (Result.Ok, oIntent);
        }
    else
        SetResult(Result.Canceled, oIntent);
    GC.Collect();
    Finish();
}

드디어

protected override void OnActivityResult(int iRequestCode, Android.App.Result oResultCode, Intent oIntent)
{
    base.OnActivityResult (iRequestCode, oResultCode, oIntent);
    iValue = oIntent.Extras.GetInt("MYVALUE", -1); //=> 1234567890
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.