在杀死和恢复活动后恢复对象引用

时间:2012-08-31 02:57:50

标签: android android-fragments android-viewpager

我有一个FragmentPagerAdapter,可以浏览自定义SurveyPage类生成的视图。寻呼机的最后一页由SurveyFinishPage生成,它试图访问与FragmentPagerAdapter相关的调查,并将所有调查答案一起拉出来显示它们。 SurveyFinishPage通过主Activity中的getSurvey()方法获取Survey对象。

通常这样可以正常工作,并且SurveyFinishPage能够访问FragmentPagerAdapter正在使用的相同Survey对象。但是,如果活动已经被杀死并恢复,则SurveyFinishPage似乎仍然在访问旧的Survey(或者可能是它的副本) - 它显示了在放弃Activity之前的答案,无论对新的,已重建的答案的更改如何调查。

似乎在我的MainActivity中恢复onRestoreInstanceState()中aSurvey的值应该为其他所有内容建立调查对象,因为MainActivity将其Survey对象传递给FragmentPagerAdapter,后者使用该对象制作片段......但是它似乎FragmentPagerAdapter和SurveyFinishPage正在研究两种不同的东西。

如何正确恢复FragmentPagerAdapter中片段的状态,以便它们都引用相同的Survey对象?

MainActivity.java

public class MainActivity extends FragmentActivity {
    SurveyPagerAdapter mSurveyPagerAdapter;
    ViewPager mViewPager;
    Survey aSurvey;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_poll);

        if(savedInstanceState != null) {
            testSurvey = savedInstanceState.getParcelable("survey");
        }
        else {
            testSurvey = new Survey();
        }
        mSurveyPagerAdapter = new SurveyPagerAdapter(getSupportFragmentManager(), aSurvey);
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSurveyPagerAdapter);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("survey", aSurvey);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        aSurvey = (Survey)savedInstanceState.getParcelable("survey");
    }
    [...]
}

SurveyPagerAdapter.java

public class SurveyPagerAdapter extends FragmentPagerAdapter {
    private Survey survey;
    [...]

    @Override
    public Fragment getItem(int i) {
        Fragment fragment;
        Bundle args = new Bundle();

        // index 0 is the title page
        if(i == 0) {
            fragment = new SurveyTitlePage();
        }
        // final index is the finish page
        else if(i == getCount()-1) {
            fragment = new SurveyFinishPage();
        }
        // all other indices are regular poll pages
        else {
            args.putParcelable("question", survey.getQuestion(i-1));
            fragment = new SurveyPage();
            fragment.setArguments(args);
        }

        return fragment;
    }
    [...]
}

SurveyFinishPage.java

public class SurveyFinishPage extends Fragment {
    private Survey survey;
    [...]

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    setSurvey(((MainPoll)getActivity()).getSurvey());
    LinearLayout view = new LinearLayout(getActivity());
    view.setOrientation(LinearLayout.VERTICAL);

    Button finishButton = new Button(getActivity());
    finishButton.setText("FINISH");

        final TextView textView = new TextView(getActivity());
        finishButton.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                String output = "";

                for(int i=0; i<survey.getSize(); i++) {
                    try {
                        output += survey.getQuestion(i).getPrompt() + " - " + survey.getQuestion(i).getAnswer() + "\n";
                    } catch (Exception e) {
                        output += survey.getQuestion(i).getPrompt() + " - " + "no answer\n";
                    }
                }
                textView.setText(output);
            }
        });

        view.addView(finishButton);
        view.addView(textView);

        return view;
    }
}

SurveyPage.java

public class SurveyPage extends Fragment {
        [...]

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            Bundle args = getArguments();
            Question question = args.getParcelable("question");
            View pageView = question.getQuestionView(getActivity(), container);
        return pageView;
    }
}

1 个答案:

答案 0 :(得分:1)

您可以将Survey对象提升到Android应用程序类并将其作为单例引用。这个答案可能会产生一些争议,但它是解决问题的合理方法。 Android保证只有1个应用程序实例,因此您可以确定(在合理范围内)您只有1个调查实例。

http://developer.android.com/guide/faq/framework.html

Singleton类

您可以通过使用单例来利用应用程序组件在同一进程中运行的事实。这是一个只有一个实例的类。它有一个静态方法,其名称如getInstance()可返回实例;第一次调用此方法时,它会创建全局实例。因为所有调用者都获得相同的实例,所以他们可以将其用作交互点。例如,活动A可以检索实例并调用setValue(3);稍后的活动B可以检索实例并调用getValue()来检索最后一个设置值。