Android片段未保存状态

Android片段未保存状态,android,android-fragments,savestate,Android,Android Fragments,Savestate,我最近将我的应用程序从基于活动的应用程序转换为基于片段的应用程序。这是一个记分应用程序,当它是一项活动时,我可以很容易地保存和恢复分数。然而,这似乎不是一个片段。这是我的密码: @Override public void onSaveInstanceState(Bundle savedInstanceState){ super.onSaveInstanceState(savedInstanceState); if(t!=null&&flag==1){

我最近将我的应用程序从基于活动的应用程序转换为基于片段的应用程序。这是一个记分应用程序,当它是一项活动时,我可以很容易地保存和恢复分数。然而,这似乎不是一个片段。这是我的密码:

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

    if(t!=null&&flag==1){
        savedInstanceState.putInt("time", t.getTimeLeft());
    } else {
        savedInstanceState.putInt("time", 0);
    }

    savedInstanceState.putIntArray("score_array", points);
    savedInstanceState.putIntArray("position_array", spinnerPosition);
    savedInstanceState.putBooleanArray("checked_array", shouldBeChecked);

    flag = 0;
    Log.d("MyApp", "savingState");
}

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

    Log.d("MyApp", "onActivityCreated");

    try {
        int timeLeft = savedInstanceState.getInt("time");

        points = savedInstanceState.getIntArray("score_array").clone();
        spinnerPosition = savedInstanceState.getIntArray("position_array").clone();
        shouldBeChecked = savedInstanceState.getBooleanArray("checked_array").clone();

        ((BaseAdapter) ((ListView)getView().findViewById(R.id.missionList)).getAdapter()).notifyDataSetChanged();

        if(timeLeft!=0){
            flag=1;

            this.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

            t = new TimerClass(timeLeft*1000, 1000);
            t.setViews((TextView)getView().findViewById(R.id.minuteView), (TextView)getView().findViewById(R.id.tenSecondView), (TextView)getView().findViewById(R.id.secondView), (Button)getView().findViewById(R.id.start_button));
            ((Button)getView().findViewById(R.id.start_button)).setText(R.string.stop);
            t.start();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } 

}

我在
onrestoreinnstancestate
中的活动中成功地使用了完全相同的代码,而不是在创建的活动中使用了
onActivityCreated
并且没有try/catch。问题是,当我尝试从包中提取某些内容时,会出现空指针错误。我可以在日志中看到保存状态,然后是onActivityCreated,但onActivityCreated似乎没有通过onSavedInstanceState获取放入包中的内容。我只是在调用
savedInstanceState.getAnything()
的每一行上得到一个空指针。但是,据我所知,
onCreate
onCreateView
、以及
onActivityCreated
都使用相同的捆绑包。我曾尝试将代码移到另外两个,但没有成功。

我最终找到了一个相当粗糙的解决方法。因为它并没有真正解决核心问题,所以对此并不感到兴奋。如果有人能帮我找到答案,我很乐意接受这个答案


也就是说,我只是使用活动的onSaveInstanceState和onRestoreInstanceState来保存和恢复片段数据。

对于需要更好答案的人:

在访问它之前,请始终测试
if(savedInstanceState!=null)
,以避免出现空指针错误。 另外,请注意,当片段被销毁时,onSaveInstanceState()无法在所有情况下保存数据

特别是如果你的碎片被推到后堆栈上,并且设备被旋转。在这种情况下,当片段被推到后堆栈上时,只有onDestoryView()会被调用,因此当onSaveInstanceState()在设备旋转期间运行时,它将无法保存视图中的任何数据,因为它们之前都已被销毁

请参阅以下线程了解解决方法。我认为它对使用片段开发的每个人都很有用。 尤其是DroidT的回答:

您是否确保在onSaveState方法中未在捆绑包中保存空值?非常确定。它们被初始化为非null,我看不到任何使它们变为null的方法。它作为一个活动一行一行地工作。刚刚检查过,绝对不是空的。很难从给定的代码中说出来。作为片段的onCreate方法的替代方法,您可以调用方法“setRetainInstance(true)”,它将跨方向更改保留数据。你只需要确保不保留任何以前的活动引用,以避免内存泄漏。今天下午有机会时我会这样做。你能进一步解释一下你之前提到的活动是什么意思吗?您是说创建此片段的多个实例,而setRetainInstance()将保留所有实例吗?我已经确定我只创建了一次片段,并且每次它出现在屏幕上时都打开相同的片段。另外,你说很难从给定的代码中分辨出来。还有哪些代码可能有用。我发布这篇文章是因为它是所有与保存/恢复状态相关的代码。如果还有其他有用的东西,我会尝试发布它。我想您可能每次都在重新创建片段,请输入如何将此片段附加到活动的代码。若活动被重新创建,若通过特定设备上的代码添加,它将丢失其先前的片段。我也有同样的问题。最后调用了setContentView(myxml),myxml中包含了片段类