2012-06-12 12 views
7

यहाँ बहाल करने में दो बार कहा जाता है मैं मेरी समस्या प्रदर्शित करने के लिए बना लिया है एक सरल Android एप्लिकेशन है:एंड्रॉयड onCreateOptionsMenu जब राज्य

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; 
    } 
} 

टुकड़ा:

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"); 
    } 
} 

लेआउट सिर्फ एक में टुकड़ा डंप करने के लिए LinearLayout है :

<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> 

बहुत आसान अधिकार? जब मैं इसे चलाने मैं निम्नलिखित आउटपुट प्राप्त की उम्मीद के रूप में:

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 

क्यों गतिविधि onCreateOptionMenu और टुकड़ा onCreateOptionsMenu दो बार कहा जाता है:

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 

अब जब मैं फोन बारी बारी से मैं कुछ अजीब व्यवहार मिल सकता है? अगर मैं टुकड़ा से विकल्प मेनू को दूर मैं गतिविधि के लिए 1 कॉल प्राप्त onCreateOptionsMenu अपेक्षा के अनुरूप:

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 

मुझे समझ नहीं आता और ने इस और कोई भी इस समस्या का सामना करना पड़ा रहा है। असली समस्या यह है कि मेरा सर्च व्यू कॉन्फ़िगरेशन चेंज (फोन घुमाने) पर इसकी स्थिति को पुनर्प्राप्त करने में सक्षम नहीं है क्योंकि ऑनक्रेटऑप्शनमेनू को दो बार बुलाया जा रहा है। पहली बार ऐसा लगता है कि यह राज्य है लेकिन दूसरी बार इसे साफ़ कर दिया गया है और रीसेट कर दिया गया है। मैं यह समझने में सक्षम नहीं हूं कि मैं क्या गलत कर रहा हूं।

अग्रिम धन्यवाद।

+0

मुझे लगता है कि अपने सबसे अच्छे शॉट स्रोत कोड पर भी नियंत्रण प्राप्त और डीबगर के साथ से निकलने के लिए होगा है। एंड्रॉइड में बहुत अच्छी तरह से एक बग हो सकता है। –

+0

मैंने इस समस्या पर कोई प्रगति नहीं की है। मैंने कोड के माध्यम से कदम उठाया है लेकिन दृश्यों के पीछे खंड/गतिविधि जीवन चक्र के साथ पर्याप्त परिचित नहीं है यह जानने के लिए कि क्या हो रहा है या समस्या क्या हो सकती है। मुझे अभी एक कामकाज मिला है कि यह सुंदर "हैकी" है लेकिन मैं आगे बढ़ रहा हूं। अगर कोई उत्तर के साथ आता है तो मुझे बताएं। धन्यवाद! – Dave

+0

मुझे एक ही समस्या है। 'onCreateOptionMenu' और' onPrepareOptionsMenu' को दो बार बुलाया जाता है और दूसरी बार वे मेनू स्थिति को रीसेट करते हैं। अभी तक कोई समाधान नहीं मिला है :( –

उत्तर

5

मुझे लगता है कि मुझे इस समस्या का उत्तर मिला है।

एक यह एक नज़र डालें:

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

समस्या तथ्य यह है कि एंड्रॉयड टुकड़ा जब गतिविधि नष्ट हो जाता है (जब उपकरण घुमाया जाता है) को नष्ट नहीं करता से संबंधित जा रहा है।

असल में मैं कहा:

setRetainInstance(true); 

मेरी टुकड़ा निर्माता और समस्या का हल जाने।

उम्मीद है कि यह मदद करता है!

अपने उदाहरण में दोनों Activity और Fragment रोटेशन पर नष्ट कर दिया और फिर से बनाया हो:

+3

हां! बहुत बहुत धन्यवाद। इसने मेरी समस्या हल की। ​​ दिलचस्प बात यह है कि गतिविधि में यह विकल्प भी है यदि कोई खंड विकल्प मेनू में भाग ले रहा है और setRetainInstance (true) को कॉल नहीं करता है , भले ही सर्च व्यू गतिविधि द्वारा जोड़ा गया हो। अगर आप खंड से setHasOptionsMenu को हटाते हैं, तो गतिविधि SearchView सामान्य रूप से व्यवहार करती है। मुझे लगता है क्योंकि नया जोड़ा हुआ टुकड़ा क्रिएटऑप्शनमेनू पर गतिविधियों को फिर से बुलाता है। – Dave

2

@Gerardo Contijoch जवाब एक तथ्य के अलावा भ्रामक है,। यही कारण है कि onCreateOptionsMenu() को दो बार बुलाया जाता है। यह सही और अपेक्षित व्यवहार है।

setRetainInstance(true) द्वारा आप एंड्रॉइड को खंड को नष्ट न करने के लिए कहते हैं। यूआई-कम खंड वाले कोई गतिविधि 'संदर्भ (AsyncTasks समन्वय के लिए उपयोगी और कुछ अन्य सेवा जैसी सामग्री) के मामले में उपयोगी साबित हो सकता है।

अन्य मामलों में यह संभावित रूप से स्मृति रिसाव की ओर जाता है, जिसे आप टालना चाहते हैं।

0

मैं सिर्फ बढ़ा-चढ़ाकर से पहले मेनू को मंजूरी दे दी और काम करता है

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     menu.clear(); 
     inflater.inflate(R.menu.call_menu, menu); 
     super.onCreateOptionsMenu(menu, inflater); 

} 
संबंधित मुद्दे