android - RequestPermissionsResult() के भीतर से डायलॉग फ्रैगमेंट का शो() कॉल करना मार्शमलो में अवैध स्टेटएक्स अपवाद का कारण बनता है




android-fragments android-dialogfragment (5)

इस तरह कुछ कोशिश करें:

// ...
private Runnable mRunnable;

@Override
public void onResume() {
   super.onResume();

   if (mRunnable != null) {
       mRunnable.run();
       mRunnable = null;
   }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
   super.onRequestPermissionsResult(requestCode, permissions, grantResults);

   if (/* PERMISSION_DENIED */) {
      mRunnable = /* new Runnable which show dialogFragment*/;
   }
}

कदम:

  1. Fragment या Activity से अनुमति का अनुरोध करें
  2. onRequestPermissionsResult() भीतर से एक संवाद फ़्रेगमेंट दिखाएं
  3. java.lang.IllegalStateException फेंक दिया गया है: onSaveInstanceState इस क्रिया को निष्पादित नहीं कर सकता

ऐसा तब नहीं होता जब मैं कुछ देरी के बाद संवाद दिखाता हूं (पोस्टडेलेड का उपयोग करके)। http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html ) के बाद onStop() डिवाइस पर हम किसी भी राज्य हानि के बिना onPause() और onStop() या अपवाद। नमूना प्रोजेक्ट स्रोत, लॉग फ़ाइल और दर्ज की गई समस्या का एक लिंक यहां दिया गया है। https://drive.google.com/folderview?id=0BwvvuYbQTUl6STVSZF9TX2VUeHM&usp=sharing

इसके अलावा मैंने एक मुद्दा https://code.google.com/p/android/issues/detail?id=190966 खोला है, लेकिन इसे वर्किंगएसइन्टेंड के रूप में चिह्नित किया गया था और वे केवल अपवाद पकड़ने का सुझाव देते हैं। लेकिन यह इस मुद्दे को हल नहीं करता है। मैं इसे हल करने के अन्य तरीकों को जानता हूं, लेकिन यह एंड्रॉइड बग नहीं है?

बग के लिए अद्यतन स्थिति फिर से "असाइन" है। उम्मीद है कि यह जल्द ही तय हो जाएगा। मेरा अस्थायी समाधान है

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        // do your fragment transaction here
    }
}, 200);

चूंकि आप DialogFragment का उपयोग कर रहे हैं, इसलिए आपको फ्लैग या DialogFragment रखना चाहिए और अपने संवाद को onPostResume में onPostResume । आपको इसे onResume या अन्य जीवन चक्र विधियों के बजाय onPostResume में करना चाहिए।

जैसा कि documentation स्पष्ट रूप से बताता है, यदि आप onPostResume या onResumeFragments (फ्रैगमेंट onResumeFragments लिए) के अलावा गतिविधि जीवन चक्र विधियों में लेनदेन करते हैं, तो कुछ मामलों में गतिविधि की स्थिति को पूरी तरह से बहाल करने से पहले विधि को बुलाया जा सकता है।

इसलिए, यदि आप पोस्टरस्यूम पर अपना संवाद दिखाते हैं तो आप ठीक होंगे।


बग स्वीकार किया जाता है और तय किया जाएगा, हालांकि, मैं पोस्टडेड और टाइमर समाधानों से दृढ़ता से असहमत हूं। ऐसा करने का सबसे अच्छा तरीका गतिविधि में एक राज्य ध्वज पेश करेगा, जिसमें आप कॉलबैक में सेट करते हैं, और रेज़्यूम या इसी तरह के उपयोग में उपयोग करते हैं। उदाहरण के लिए:

private boolean someFlag;

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
// some code checking status
    someFlag = true;
}

और फिर रेस्यूम में:

protected void onResume() {
    if(someFlag == true) {
        doSomething();
        someFlag = false;
    }
}

मुझे यह भी लगता है कि यह एंड्रॉइड बग है। मुझे विश्वास नहीं है कि उन्होंने आपकी समस्या को चिह्नित किया है। एंड्रॉइड लोगों को ठीक से ठीक करने तक, केवल onRequestPermissionsResult() लिए केवल समाधान समाधान पर onRequestPermissionsResult() है।

अगर कोई सोच रहा है कि निष्पादन में देरी कैसे करें, तो यह इस मुद्दे को हल करने का मेरा तरीका है:

  @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    if (requestCode == PERMISSION_CODE) {
      if (/* PERMISSION ALLOWED/DENIED */) {
          new Timer().schedule(new TimerTask() {
              @Override public void run() {
                  // EXECUTE ACTIONS (LIKE FRAGMENT TRANSACTION ETC.)
              }
          }, 0);
      }
  }

यह अनिवार्य रूप से निष्पादन में देरी करता है जब तक कि onRequestPermissionsResult() समाप्त नहीं होता है, इसलिए हमें java.lang.IllegalStateException नहीं मिलता है। यह मेरे ऐप में काम करता है।


यह एंड्रॉइड में एक बग है https://code.google.com/p/android/issues/detail?id=190966&q=label%3AReportedBy-Developer&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars डेवलपर&colspec=ID%20Type%20Status%20Owner%20Summary% https://code.google.com/p/android/issues/detail?id=190966&q=label%3AReportedBy-Developer&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars

तो, अभी के लिए, कामकाज जरूरी है। आप @ ldulcic के समाधान का उपयोग कर सकते हैं। या आप हैंडलर की पोस्टडेले विधि का उपयोग कर सकते हैं। दूसरा विकल्प पसंद किया जाता है।





android-6.0-marshmallow