Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
532 views
in Technique[技术] by (71.8m points)

android onCreateOptionsMenu called twice when restoring state

Here's a simple android app I've created to demonstrate my problem:

public class OptionMenuTest extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("test", "create activity");
        setContentView(R.layout.options_layout);
        if(getFragmentManager().findFragmentByTag("frag") == null) {
            getFragmentManager().beginTransaction().add(R.id.option_fragment_container, new OptionMenuFragment(), "frag").commit(); 
        }

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        Log.d("test", "saving Activity state");
        super.onSaveInstanceState(outState);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Log.d("test", "create Activity options menu");
        menu.add("activity");
        return true;
    }
}

Fragment:

public class OptionMenuFragment extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("test", "create fragment");
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        TextView tv = new TextView(getActivity());
        tv.setText("Hello world");
        Log.d("test", "create fragment view");
        return tv;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add("fragment");
        Log.d("test", "create fragment options menu");
    }
}

Layout is just a LinearLayout to dump the fragment into:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/option_fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
</LinearLayout>

Very simple right? When I run it I get the following output as expected:

06-12 15:42:51.415: D/test(957): create activity
06-12 15:42:51.446: D/test(957): create fragment
06-12 15:42:51.446: D/test(957): create fragment view
06-12 15:42:51.446: D/test(957): create Activity options menu
06-12 15:42:51.446: D/test(957): create fragment options menu

Now when I rotate the phone I get some strange behavior:

06-12 15:43:11.251: D/test(957): saving Activity state
06-12 15:43:11.290: D/test(957): create fragment
06-12 15:43:11.290: D/test(957): create activity
06-12 15:43:11.306: D/test(957): create fragment view
06-12 15:43:11.306: D/test(957): create Activity options menu
06-12 15:43:11.306: D/test(957): create fragment options menu
06-12 15:43:11.306: D/test(957): create Activity options menu
06-12 15:43:11.306: D/test(957): create fragment options menu

Why is the activity onCreateOptionMenu and fragment onCreateOptionsMenu called twice? If I remove the options menu from the fragment I get 1 call to the activity onCreateOptionsMenu as expected:

06-12 15:50:03.610: D/test(1076): create fragment
06-12 15:50:03.610: D/test(1076): create fragment view
06-12 15:50:03.813: D/test(1076): create Activity options menu
06-12 15:50:08.392: D/test(1076): saving Activity state // <-- rotate happens here
06-12 15:50:08.446: D/test(1076): create fragment
06-12 15:50:08.446: D/test(1076): create activity
06-12 15:50:08.462: D/test(1076): create fragment view
06-12 15:50:08.470: D/test(1076): create Activity options menu

I don't understand this and no one else seems to have encountered this problem. The real problem is that my SearchView is not able to recover it's state on config change (phone rotate) because the onCreateOptionMenu is being called twice. The first time it seems to have it's state but the second time it's cleared out and reset. I'm not able to figure out what I'm doing wrong.

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I think I found the answer to this problem.

Take a look a this:

https://stackoverflow.com/a/7225296/48468

The problem seems to be related to the fact that Android does not destroy the fragment when the activity is destroyed (when the device is rotated).

Basically I added :

setRetainInstance(true);

to my fragment constructor and the problem go solved.

Hope it helps!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...