Добавление дополнительных параметров в Bundle, вызывающее странные конфликты и сбой приложения... Почему?

Я сталкиваюсь со странной ошибкой в ​​основной активности приложения.

у меня есть FragmentStatePagerAdapter в моей деятельности (как внутренний класс), с его instantiateItem(ViewGroup container, int position) метод переопределен для обработки изменений ориентации.

Этот метод работал нормально, пока я не поместил String в Bundle через onSaveInstanceState(Bundle outState), Когда метод реализован так, instantiateItem не называется:

 @Override
protected void onSaveInstanceState(Bundle outState){
    if (myObject != null) {
        outState.putString(MY_OBJECT_KEY, myObject.getName());
    }
    super.onSaveInstanceState(outState);
}

Когда я удаляю outState.putString(MY_OBJECT_KEY, myObject.getName()) instantiateItem вызывается без проблем каждый раз, когда изменяется ориентация. Почему это? Любая помощь действительно ценится.

Я получаю следующую ошибку:

E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.android.miki.rpiplantsapp, PID: 22292                                     
   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.miki.rpiplantsapp/com.android.miki.rpiplantsapp.PlantStatsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.miki.rpiplantsapp.MoistureFragment.setOptimalStatText(java.lang.String)' on a null object reference
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
       at android.app.ActivityThread.-wrap15(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5422)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.miki.rpiplantsapp.MoistureFragment.setOptimalStatText(java.lang.String)' on a null object reference
       at com.android.miki.rpiplantsapp.PlantStatsActivity$ViewPageAdapter.updateCurrentFragsOptimal(PlantStatsActivity.java:733)
       at com.android.miki.rpiplantsapp.PlantStatsActivity.loadPlantItemTabs(PlantStatsActivity.java:426)
       at com.android.miki.rpiplantsapp.PlantStatsActivity.onCreate(PlantStatsActivity.java:225)
       at android.app.Activity.performCreate(Activity.java:6251)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 
       at android.app.ActivityThread.-wrap15(ActivityThread.java) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:148) 
       at android.app.ActivityThread.main(ActivityThread.java:5422) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Метод instantiateItem выглядит так:

@Override
    public Object instantiateItem(ViewGroup container, int position){
        switch (position){
            case 0:
                MoistureFragment moistureTab = (MoistureFragment) super.instantiateItem(container, position);
                currentMoistureFragment = moistureTab;
                return currentMoistureFragment;

            case 1:
                LightFragment lightTab = (LightFragment) super.instantiateItem(container, position);
                currentLightFragment = lightTab;
                return currentLightFragment;
            case 2:
                TemperatureFragment tempTab = (TemperatureFragment) super.instantiateItem(container, position);
                currentTempFragment = tempTab;
                return currentTempFragment;
            default:
                return null;
        }
    }

updateCurrentFragsOptimal () выглядит следующим образом:

   public void updateCurrentFragsOptimal(double moistureValue, double lightValue, double tempValue){
        currentMoistureFragment.setOptimalStatText(String.valueOf(moistureValue));
        currentLightFragment.setOptimalStatText(String.valueOf(lightValue));
        currentTempFragment.setOptimalStatText(String.valueOf(tempValue));
    }

2 ответа

Ну, это было проще, чем я думал... Я понял, что я вызвал метод в моем onCreate() метод, когда savedInstanceState не был нулевым, это вызвало другой метод. Этот метод сделал несколько вещей, которые помешали instantiateItem от вызова, и, следовательно, фрагмент оказался нулевым и вызвал исключение NullPointerException. Просто простая ошибка в логике.

При переопределении onSaveInstanceState() вы должны вызывать код суперкласса перед вашим.

@Override
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    if (myObject != null && outState != null) {
        outState.putString(MY_OBJECT_KEY, myObject.getName());
    }
}
Другие вопросы по тегам