Значения не сохраняются в saveInstanceState

По какой-то причине значения из gridView не сохраняются из Bundle. В logcat тоже ничего не выводится. Правильно ли я получаю значения из сетки? Он полон текстов редактирования, поэтому он должен получать значения оттуда.

public class RedScorerFragment extends SherlockFragment {

LayoutInflater infl;
GridView mGrid;

int R1C1, R1C2, R1C3;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    infl = inflater;
    View mView = inflater.inflate(R.layout.fragment_score_red, container, false);
    mGrid = (GridView) mView.findViewById(R.id.gridViewRed);


    if(savedInstanceState != null)
    {
        R1C1 = savedInstanceState.getInt("R1C1");
        R1C2 = savedInstanceState.getInt("R1C2");
        R1C3 = savedInstanceState.getInt("R1C3");

        Log.d("savedd R1C1 ", String.valueOf(R1C1));
        Log.d("savedd R1C2 ", String.valueOf(R1C2));
        Log.d("savedd R1C3 ", String.valueOf(R1C3));
    }


    mGrid.setAdapter(new ImageAdapter(getActivity()));
    return mView;
}

@Override
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);

    if(savedInstanceState != null)
    {
        R1C1 = savedInstanceState.getInt("R1C1", 0);
        R1C2 = savedInstanceState.getInt("R1C2", 0);
        R1C3 = savedInstanceState.getInt("R1C3", 0);

        Log.v("saved R1C1 ", String.valueOf(R1C1));
        Log.v("saved R1C2 ", String.valueOf(R1C2));
        Log.v("saved R1C3 ", String.valueOf(R1C3));
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState){
    super.onSaveInstanceState(savedInstanceState);

    //for(int i=0;i<mGrid.getChildCount(); i++)
    Log.e("Saving", mGrid.getChildAt(0).toString());
    Log.e("Saving", mGrid.getChildAt(1).toString());
    Log.e("Saving", mGrid.getChildAt(2).toString());
    savedInstanceState.putInt("R1C1", Integer.valueOf(mGrid.getItemAtPosition(0).toString()) );
    savedInstanceState.putInt("R1C2", Integer.valueOf(mGrid.getItemAtPosition(1).toString()) );
    savedInstanceState.putInt("R1C3", Integer.valueOf(mGrid.getItemAtPosition(2).toString()) );

}

}

Логкэт

12-22 23:58:38.736: E/AndroidRuntime(2481): FATAL EXCEPTION: main
12-22 23:58:38.736: E/AndroidRuntime(2481): java.lang.RuntimeException: Unable to pause activity {org.say.upscorer/org.say.upscorer.MainActivity}: java.lang.NullPointerException
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3348)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3305)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3288)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.ActivityThread.access$2500(ActivityThread.java:125)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2040)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.os.Looper.loop(Looper.java:123)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.ActivityThread.main(ActivityThread.java:4627)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at java.lang.reflect.Method.invokeNative(Native Method)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at java.lang.reflect.Method.invoke(Method.java:521)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at dalvik.system.NativeStart.main(Native Method)
12-22 23:58:38.736: E/AndroidRuntime(2481): Caused by: java.lang.NullPointerException
12-22 23:58:38.736: E/AndroidRuntime(2481):     at org.saywatt.scoring.RedScorerFragment.onSaveInstanceState(RedScorerFragment.java:91)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.support.v4.app.Fragment.performSaveInstanceState(Fragment.java:1607)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1587)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1655)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:527)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at com.actionbarsherlock.app.SherlockFragmentActivity.onSaveInstanceState(SherlockFragmentActivity.java:127)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.Activity.performSaveInstanceState(Activity.java:1036)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1180)
12-22 23:58:38.736: E/AndroidRuntime(2481):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3330)
12-22 23:58:38.736: E/AndroidRuntime(2481):     ... 12 more

person rasen58    schedule 23.12.2012    source источник


Ответы (4)


Семейство функций Bundle::get принимает в качестве параметра тег или id. Так они узнают, что именно вы просите. то есть,

// get a String with id "R1C1", note the quotes
R1C1 = savedInstanceState.getString("R1C1");

То, как вы их вызываете, что работает случайно, поскольку вы имеете дело с Strings, на самом деле запрашивает String с id того, что R1C1 содержит в данный момент.

Но вы помещаете ints в пакет и ожидаете извлечь Strings, это обычная и простая ошибка.

person K-ballo    schedule 23.12.2012
comment
Я обновил код в сообщении, чтобы использовать целые числа, и он все еще отображается в logcat. - person rasen58; 23.12.2012
comment
@ rasen58: Вы заметили, что на onSaveInstanceState вы записываете одно, а сохраняете другое, верно? - person K-ballo; 23.12.2012
comment
Я получаю исключение нулевого указателя, когда делаю mGrid.getItemAtPosition - person rasen58; 23.12.2012
comment
@ rasen58: Вы уверены, что исключение возникает при выполнении mGrid.getItemAtPosition(), а не при последующем .toString()? - person K-ballo; 23.12.2012
comment
Нажимаю кнопку домой, а он вылетает. я выложил лог кота - person rasen58; 23.12.2012
comment
Думаю, я знаю, почему. Кажется, что Integer.valueOf((String) mGrid.getItemAtPosition(0)) всегда возвращает ноль - person rasen58; 23.12.2012

Как родитель Activity объявлен в вашем манифесте? Если вы обрабатываете изменения конфигурации, т.е.

android:configChanges= whatever

ваш Activity и, следовательно, ваш Fragment не будут воссозданы.

person Christopher Perry    schedule 23.12.2012
comment
О, у меня нет никаких изменений в конфигурации ‹application android:allowBackup=true android:icon=@drawable/ic_launcher android:label=@string/app_name android:theme=@style/Theme.Sherlock › - person rasen58; 23.12.2012
comment
Это объявление приложения. Можете ли вы опубликовать то, что у вас есть для Activity? - person Christopher Perry; 23.12.2012

Вы, вероятно, еще одна жертва автоматического (не)боксинга. Я подозреваю, что, поскольку Bundle.putInt() принимает int в качестве второго аргумента, в то время как вы предоставляете ему значение Integer.valueOf(), которое возвращает Integer. Ничего страшного, если возвращенное Integer не будет null, но при распаковке просто не удастся преобразовать null в обычное int, что приведет к NPE.

Что делать, зависит от конкретного случая и от того, что делает ваше приложение. В любом случае убедитесь, что Integer.valueOf() не возвращает null.

person andr    schedule 23.12.2012

Если вы устанавливаете

setRetainInstance(true) 

внутри вашего фрагмента или установить его из действия:

myFragment.setRetainInstance(true):

тогда пакет, переданный от onSaveInstanceState() к onCreate() и onCreateView(), будет нулевым, даже если вы добавите к нему дополнительные функции в onSaveInstanceState().

Смотрите этот ответ: как я могу сломать фрагменты с помощью setRetainInstance(true) и добавить их в стопку?

person onosendai    schedule 23.12.2012
comment
У меня нигде нет setRetainInstance(true). Мне это нужно? - person rasen58; 23.12.2012
comment
Я упомянул об этом, поскольку он несовместим с использованием onSaveInstanceState() во фрагменте, и если вы где-то его вызвали, это может вызвать описанную вами проблему. Если вы используете onSaveInstanceState для передачи пакета, не используйте setInstanceState(). Если вы хотите узнать больше о том, что он делает, см. здесь: stackoverflow.com/questions /11182180/ - person onosendai; 23.12.2012