簡體   English   中英

無法還原嵌套片段狀態

[英]Unable to restore nested fragment state

我在還原嵌套片段的狀態時遇到問題。 這是層次結構:

MainActivity

----> AlarmOverviewFragment (實際上不保存任何重要數據)

--------> AlarmFragment (保存數據)

我遇到的問題是,當我最小化應用程序(按“主頁”按鈕)然后重新打開應用程序時,每次嘗試從存儲為onCreateView()Fragment實例變量之一存儲的數組中獲取數據時,它都會崩潰。

令人沮喪的是,我將實例變量保存在onSaveInstanceState() ,但在onCreateView()onCreate()onActivityCreated()savedInstanceState始終為null。

顯然,我在這里錯過了一些巨大的東西,因為我嘗試了許多關於stackoverflow的解決方案,但都沒有用。 以下是一些相關的代碼位:

保存實例數據:

@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putInt("hour", this.hour);
    outState.putInt("window", this.window);
    outState.putInt("minutes", this.minutes);
    outState.putBooleanArray("days", this.days);
    super.onSaveInstanceState(outState);
}

嘗試還原數據失敗

@Override
public void onCreate(Bundle savedInstanceState) {

    if (savedInstanceState != null) {
        /* Never happens */
        hour = savedInstanceState.getInt("hour");
        window = savedInstanceState.getInt("window");
        minutes = savedInstanceState.getInt("minutes");
        days = savedInstanceState.getBooleanArray("days");
    }
    super.onCreate(savedInstanceState);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        /* Also never happens */
    }
    super.onActivityCreated(savedInstanceState);
}

為了以防萬一,這是堆棧跟蹤:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: group12.wakemeup, PID: 22756
                  java.lang.RuntimeException: Unable to resume activity {group12.wakemeup/group12.wakemeup.MainActivity}: java.lang.NullPointerException: Attempt to read from null array
                      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3121)
                      at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1400)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5525)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
                   Caused by: java.lang.NullPointerException: Attempt to read from null array
                      at group12.wakemeup.AlarmFragment.onCreateView(AlarmFragment.java:113)
                      at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295)
                      at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
                      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682)
                      at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
                      at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607)
                      at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:181)
                      at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1237)
                      at android.app.Activity.performStart(Activity.java:6288)
                      at android.app.Activity.performRestart(Activity.java:6334)
                      at android.app.Activity.performResume(Activity.java:6339)
                      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3110)
                      at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1400) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:148) 
                      at android.app.ActivityThread.main(ActivityThread.java:5525) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 

編輯

額外的信息

每個AlarmFragment是動態添加的,並通過View.generateViewId()賦予了唯一的ID,因此我不確定如何在MainActivity保存每個片段。 還值得一提的是,我確實使用FragmentPagerAdapter來處理選項卡/刷卡操作(此應用程序中還有其他Overview片段,但由於它們不會給我帶來麻煩,所以我將其省略了)。 我聽說有一種使用ViewPager來保存狀態的方法,也許還有一種帶有FragmentPagerAdapter方法?

嘗試將片段保存在活動中

private YourFragment yourFragment;

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //Save the fragment instances
    getFragmentManager().putFragment(outState, "any string you want as key", yourFragment);
    //or use code below if you use android.support.v4.app.Fragment 
    //getSupportFragmentManager().putFragment(outState, "any string you want as key", yourFragment);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        //retrieve your fragment that saved from onSaveInstanceState()
        yourFragment = (YourFragment) getFragmentManager().getFragment(savedInstanceState, "any string you want as key");
        //or
        //yourFragment = (YourFragment) getSupportFragmentManager().getFragment(savedInstanceState, "any string you want as key");
    }
    else {
        //create your fragment if it is first time
        yourFragment = new YourFragment();
    }
}

由於問題似乎與開始時有所不同,因此實際上您不需要每次都在onNewIntent重新創建片段。 您可以改為:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if ("some_action".equals(intent.getAction())) {
        //your action, in your case create and assign fragment

        //remove the action
        intent.setAction(null);
    }
}

好吧,我想我的問題來自完全不同的事物。 MainActivity在從一系列活動返回的onNewIntent()創建了一個新的AlarmFragment ,以定義每個AlarmFragment的值。 顯然,最小化該應用程序,然后每次重新打開它都會調用onNewIntent() ,因此我的解決方案是確保我實際上是在使用數據創建新的AlarmFragments 愚蠢的問題,愚蠢的解決方案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM