2012-05-10 16 views
18

साथ दुर्घटनाग्रस्त मैं कुछ पृष्ठभूमि काम कर रहा हूँ और एक DialogFragment दिखाते हुए मैं ऐसा। एक बार मेरा काम पूरा हो जाने के बाद और प्रासंगिक कॉलबैक लागू किया जाता है, तो मैं संवाद को खारिज कर देता हूं। विशेष रूप से लाइन परDialogFragment.dismiss NullPointerException

void dismissInternal(boolean allowStateLoss) { 
     if (mDialog != null) { 
      mDialog.dismiss(); 
      mDialog = null; 
     } 
     mRemoved = true; 
     if (mBackStackId >= 0) { 
      getFragmentManager().popBackStack(mBackStackId, 
        FragmentManager.POP_BACK_STACK_INCLUSIVE); 
      mBackStackId = -1; 
     } else { 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      ft.remove(this); 
      if (allowStateLoss) { 
       ft.commitAllowingStateLoss(); 
      } else { 
       ft.commit(); 
      } 
     } 
    } 

:: जब मैं करना, मैं एक एनपीई की वजह से एक दुर्घटना एंड्रॉयड स्रोत में यहाँ मिलता है, FragmentTransaction ft = getFragmentManager().beginTransaction();

+1

क्या टुकड़ा/गतिविधि है जिससे आप पृष्ठभूमि में गए संवाद को खारिज कर रहे हैं, यानी इसकी 'ऑन पॉज़' विधि कहा जाता है? इस मामले में मैं समस्याओं की अपेक्षा करता हूं और यह सुनिश्चित करके इस तरह के मुद्दों के आसपास काम करता हूं कि जब तक 'ऑनर्यूम'' नहीं कहा जाता है, तब तक संवाद को खारिज करने जैसी चीजें नहीं करते हैं (सूचीबद्ध रुका हुआ हैंडलर दृष्टिकोण लागू करके [http://stackoverflow.com/प्रश्न/79 9 24 9 6/कैसे-टू-हैंडल-एसिन्टास्क-ऑनपोस्टेक्स्यूट्यूट-कब-रोका-से-बचने-अवैधस्टेक्सेप्शन), या [यहां] (http://stackoverflow.com/questions/8040280/how-to-handle-handler -मेजेज-कब-गतिविधि-खंड-रोका गया है) – PJL

+0

@ पीजेएल दिलचस्प बिंदु। मुझे लॉग ऑन करना चाहिए। कारण समझता है कि ऑन पॉज़ कहा जाएगा। मैं आपके दृष्टिकोण को एक शॉट दूंगा। – LuxuryMode

उत्तर

5

मेरे शर्त यह होगी कि कोड आप पोस्ट पृष्ठभूमि धागे से है ... आपको UI थ्रेड के अलावा कहीं भी यूआई को अपडेट करने की अनुमति नहीं है।

आप

+0

आपको समर्थन देना सर, मैं भी सोचता हूं वही ... –

+2

मैंने इसे माना। हालांकि, मुझे वही परिणाम मिलता है, भले ही मैं getActivity() चलाता हूं। runOnUi थ्रेड हालांकि मैंने वास्तव में एक AsyncTask – LuxuryMode

+0

स्थापित करने का प्रयास नहीं किया है, मुझे एक ही समस्या है और मैं पहले से ही ' यूआई थ्रेड से खारिज करें() ' –

14

यह भी हो सकता है जब आप को खारिज() इससे पहले कि आप इस शो कहा जाता है फोन (यदि मेरा अनुमान है क्या हो रहा है के बारे में सही है) अपने लक्ष्य को प्राप्त करने onPostExecute() या runOnUiThread() का उपयोग कर सकते हैं() जैसे सोगर ने कहा।

के बाद संवाद वस्तु का निर्माण किया है, लेकिन संवाद से पहले से पता चला नहीं है, अगर (mDialog! = नल) पारित किया जा सकता है और NullPointerException हो जाएगा।

जब आप जाँच लें कि mDialog अशक्त या नहीं है,

if (mDialog != null) { 
    mDialog.dismiss(); 
    mDialog = null; 
} 

नीचे की तरह अधिक की स्थिति जोड़ें,

if ((mDialog != null) && mDialog.isAdded() && mDialog.isResumed()) { 
    mDialog.dismiss(); 
    mDialog = null; 
} 

मुझे लगता है कि mDialog.isAdded() हालत काफी हो सकती है ...

+0

'isAdded() 'और' isResumed() 'की जांच अनावश्यक है - अगर एक टुकड़ा फिर से शुरू किया जाता है तो यह भी जोड़ा जाता है। [खंड जीवनचक्र दस्तावेज़] देखें (https://developer.android.com/guide/components/fragments.html#Creating)। – yuval

1

यह जांचना कि क्या यह धुंधला होने से पहले दृश्यमान है, इस शून्य सूचक अपवाद से बच सकता है

if (mDialog != null && mDialog.isVisible) { 
     mDialog.dismiss(); 
     mDialog = null; 
    } 
10

सरल समाधान "getFragmentManager()" कॉल करने से पहले "शून्य" के लिए "खारिज()" विधि की जाँच करने के लिए है। इसके अलावा, आप विस्तार कर सकते हैं "DialogFragment" वर्ग और ओवरराइड विधि "खारिज()" वहाँ यह जाँच करने के लिए:

@Override 
public void dismiss() 
{ 
    if (getFragmentManager() != null) super.dismiss(); 
} 
6

मैं जानता हूँ कि इस संदेश को पुराना है, लेकिन मैं एक ऐसी ही मामला है कि मैं रिफैक्टरिंग या बदले बिना solvew करने की जरूरत में भाग बहुत सारे कोड आशा है कि यह किसी

package com.example.playback; 

import android.os.Bundle; 
import android.support.v4.app.DialogFragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class SaferDialogFragment extends DialogFragment { 

    private boolean allowStateLoss = false; 
    private boolean shouldDismiss = false; 

    public SaferDialogFragment() { 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     //check if we should dismiss the dialog after rotation 
     if (shouldDismiss) { 
      if (allowStateLoss) 
       dismissAllowingStateLoss(); 
      else 
       dismiss(); 
     } 
    } 

    @Override 
    public void dismiss() { 
     if (getActivity() != null) { // it's "safer" to dismiss 
      shouldDismiss = false; 
      super.dismiss(); 
     } else { 
      shouldDismiss = true; 
      allowStateLoss = false; 
     } 
    } 

    @Override 
    public void dismissAllowingStateLoss() { 
     if (getActivity() != null) { // it's "safer" to dismiss 
      shouldDismiss = false; 
      super.dismissAllowingStateLoss(); 
     } else 
      allowStateLoss = shouldDismiss = true; 
    } 

    //keeping dialog after rotation 
    @Override 
    public void onDestroyView() { 
     if (getDialog() != null && getRetainInstance()) 
      getDialog().setDismissMessage(null); 
     super.onDestroyView(); 
    } 



    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     /** omitted code **/ 
     return super.onCreateView(inflater, container, savedInstanceState); 
    } 
} 
1

कॉलबैक जो शुरू हो जाती है गतिविधि है जो है या (ऑरिएंटेशन बदलने) को नष्ट कर दिया जाना चाहिए पर शायद है के लिए उपयोगी है, भी प्रगति संवाद है कि एक ही गतिविधि के साथ instantiated गया हो सकता है। यह एनपीई का कारण बन सकता है। इन प्रकार की समस्याओं को रोकने के लिए गतिविधियों पर कॉलबैक पृष्ठभूमि कार्यों से नहीं बुलाया जाना चाहिए। ओटो का उपयोग कर गतिविधि से पृष्ठभूमि कार्य दसगुणा, उदाहरण के लिए, या (हो) को नष्ट कर दिया गतिविधि लागू से पृष्ठभूमि कार्य को रोकने के।

गतिविधि के स्थिर भीतरी वर्ग:

public static class ProgressDialogFragment extends DialogFragment { 
    ProgressDialog dialog; 

    public ProgressDialogFragment() { 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     dialog = new ProgressDialog(getActivity(), getTheme()); 
     dialog.setTitle(getString(R.string.please_wait)); 
     dialog.setMessage(getString(R.string.uploading_picture)); 
     dialog.setIndeterminate(true); 
     dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
     return dialog; 
    } 

} 
गतिविधि में

ओटो सदस्यता:

@Subscribe 
public void onUploadEvent(UploadAvatarEvent uploadAvatarEvent) { 
    switch (uploadAvatarEvent.state) { 
     case UploadAvatarEvent.STATE_UPLOADING: 
      if (!mProgressDialog.isAdded()) { 
       mProgressDialog.show(getFragmentManager(), TAG_PROGRESS_DIALOG); 
      } 
      break; 
     case UploadAvatarEvent.STATE_UPLOAD_SUCCES: 
      mProgressDialog.dismiss(); 
      break; 
     case UploadAvatarEvent.STATE_UPLOAD_ERROR: 
      mProgressDialog.dismiss(); 
      break; 
    } 
} 

OnCreate() गतिविधि में:

 mProgressDialog = (ProgressDialogFragment) getFragmentManager().findFragmentByTag(TAG_PROGRESS_DIALOG); 
    if (mProgressDialog == null) { 
     mProgressDialog = new ProgressDialogFragment(); 
    } 

यह मेरा कुछ कोड है

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