Programing

savedInstanceState는 항상 null입니다.

crosscheck 2020. 11. 12. 07:55
반응형

savedInstanceState는 항상 null입니다.


이것은 내 savedInstaceState 코드입니다.

@Override
public void onSaveInstanceState(Bundle savedInstanceState) 
{
    savedInstanceState.putStringArrayList("todo_arraylist", Altodo);
    Log.v("bundle", "Saved");
    super.onSaveInstanceState(savedInstanceState);
}


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

    if (savedInstanceState != null) 
    {
        Altodo = savedInstanceState.getStringArrayList("todo_arraylist");
        Log.v("bundle", "Restored");
    }
    else
    {
        Log.v("bundle", "null");
    }

    setContentView(R.layout.main);
}

로그에는 항상 "번들 저장"태그가 표시됩니다.

그러나 onCreate방법에서는 SavedInstanceState항상 null입니다.


두 개의 활동 AB 가 확장 되는 프로젝트에서 정확히 동일한 증상 ( 문제 133394로보고 됨 )을 관찰했습니다 . 활동 A 는 주요 활동이며, 세부 정보보기 활동 B 에서 돌아올 때 항상 목록 조각 에서 for 받습니다 . 몇 시간 후이 문제는 위장의 탐색 문제로 저에게 노출되었습니다.ActionBarActivitynullsavedInstanceStateonCreate

다음은 내 설정과 관련이 있으며이 페이지의 다른 답변에서 올 수 있습니다.

  • 을 감안할 때 대답, 나는 각각의 고유 ID를 설정했는지 조각 및 활동을 확인했다.
  • 호출 onSaveInstanceState없이의 재정의가 없습니다 super.
  • 활동 A이전 버전의 Android에 대한 속성과 해당 태그를 모두 사용하여 에서 acitivy B 의 부모 로 지정됩니다 ( " 탐색 제공 "참조 ).AndroidManifest.xmlandroid:parentActivityNamemeta-data

이미와 같은 해당 생성 코드가 없으면 getActionBar() .setHomeButtonEnabled(true)활동 B 의 작업 표시 줄에 작동하는 뒤로 단추 ( < )가 있습니다. 이 버튼을 누르면 활동 A가 다시 나타나지만 (a) 모든 이전 인스턴스 상태가 손실되고 (b) onCreate 항상 호출되며 (c) savedInstanceState 항상 null.

흥미롭게도 에뮬레이터 디스플레이의 하단 가장자리에 제공된 뒤로 버튼 (왼쪽을 가리키는 열린 삼각형)을 탭하면 활동 A 가를 호출하지 않고 남아있는 그대로 (즉, 인스턴스 상태가 완전히 유지됨) 다시 나타납니다 onCreate. 그럼 내비게이션에 문제가 있을까요?

더 많은 내용을 읽은활동 B 의 뒤로 버튼을 탭하면 실행되도록 자체 탐색 지침을 구현했습니다 .

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home)
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

활동 A 의 인스턴스 상태 복원과 관련된 사항이 변경되지 않았습니다. NavUtils또한 방법을 제공 getParentActivityIntent(Activity)하고 navigateUpTo(Activity, Intent)우리가 명시 적으로 활동을 지시 할 의도 탐색 수정할 수 있도록 그 A가 설정에 따라 (제공 저장된 인스턴스 상태없이 이렇게하고) 새로운 시작되지 않습니다 FLAG_ACTIVITY_CLEAR_TOP플래그 :

설정되어 있고 시작되는 활동이 현재 작업에서 이미 실행 중이면 해당 활동의 새 인스턴스를 시작하는 대신 그 위에있는 다른 모든 활동이 닫히고이 Intent가 (이제 top) 새로운 의도로서의 오래된 활동.

내 손에 이것은 손실 된 인스턴스 상태 문제를 해결하며 다음과 같이 보일 수 있습니다.

public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId()== android.R.id.home) {
        Intent intent = NavUtils.getParentActivityIntent(this);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        NavUtils.navigateUpTo(this, intent);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

사용자 가 다른 작업 내에서 활동 B 로 직접 전환 할 수있는 다른 경우에는 이것이 완전한 솔루션이 아닐 수 있습니다 ( 여기 참조 ). 또한 사용하지 않는 동작의 동일한 해결책 NavUtils은 단순히 다음을 호출하는 것입니다 finish().

public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId()== android.R.id.home) {
        finish();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

두 솔루션 모두 내 손에서 작동합니다. 나는 원래 문제가 뒤로 버튼의 약간 잘못된 기본 구현이라고 추측하고 있으며 그 구현이 어떤 종류의 navigateUp누락을 호출하는 것과 관련이있을 수 있습니다 FLAG_ACTIVITY_CLEAR_TOP.


해당보기에 대해 설정된 ID가 있는지 확인 했습니까 (보기가있는 경우 ...). onSaveInstanceState ()는 그렇지 않으면 호출되지 않습니다.

링크를 확인하십시오 .


The state saved in this manner is not persisted. If the whole application is killed as you are doing during debugging, the bundle will always be null in onCreate.

This IMO is yet another example of awful Android documentation. It's also why most apps in the marketplace don't implement saving state properly (at all).


in Manifest add this line for activities

android:launchMode="singleTop"

for example:

<activity
        android:name=".ActivityUniversity"
        android:label="@string/university"
        android:launchMode="singleTop"
        android:parentActivityName="com.alkhorazmiy.dtm.ActivityChart">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.alkhorazmiy.dtm.ActivityChart" />
    </activity>

Shouldn't super.onSaveInstanceState(savedInstanceState); be the first line in your override?

Edit: War_Hero points out in the comments that the documentation on that topic indicates that no, it shouldn't be the first line.


How do you test it?

Imo the best way to test it is using the "Don't keep activities"-flag in Settings > Developer Options. If you don't have Developer Options in Settings, see Enabling On-device Developer Options.

  1. Open your activity
  2. Long-press home
  3. Go to another application
  4. Long-press home
  5. Go back to your application

Check your activity in AndroidManifest.xml and remove android:noHistory property if is true.

<activity
    // ....
    android:noHistory="false" />

To debug, consider implementing onRestoreInstanceState and placing a call to Log.d in this method. Then, in the emulator, hit ctrl-F11 or whatever to rotate the phone. Your call to Log.d should be hit.


Implement a method of onRestoreInstanceState and put below code there

Altodo = savedInstanceState.getStringArrayList("todo_arraylist");

I found that when I override onSaveInstanceState() and actually save some data in the Bundle, instance state is restored. Otherwise it's not.


Ive managed same way arround. Instead of handling savedInstanceState Bundle on the onCreateView method, ive handled it on onCreate method and setting the passed value to a globar variable then acessing this variable on the onCreateView method. Hope it helps.


https://developer.android.com/guide/topics/manifest/activity-element#lmode

From this you can see 'Similarly, if you navigate up to an activity on the current stack, the behavior is determined by the parent activity's launch mode.' Maybe you are in the 'standard' mode.


I was able to solve it with:

@Override public boolean onSupportNavigateUp()
{
    onBackPressed();
    return true;
}

still had parent set in the manifest. So when you press the up navigation button, now it acts like the back button.

참고URL : https://stackoverflow.com/questions/6554317/savedinstancestate-is-always-null

반응형