Android: ProgressDialog.show () getApplicationContext के साथ क्रैश हो जाता है


109

मैं समझ नहीं पा रहा हूँ कि ऐसा क्यों हो रहा है। यह कोड:

mProgressDialog = ProgressDialog.show(this, "", getString(R.string.loading), true);

ठीक काम करता है। हालाँकि, यह कोड:

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

निम्नलिखित अपवाद फेंकता है:

W/WindowManager(  569): Attempted to add window with non-application token WindowToken{438bee58 token=null}.  Aborting.
D/AndroidRuntime( 2049): Shutting down VM
W/dalvikvm( 2049): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
E/AndroidRuntime( 2049): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 2049): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tastekid.TasteKid/com.tastekid.TasteKid.YouTube}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.access$2100(ActivityThread.java:116)
E/AndroidRuntime( 2049):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
E/AndroidRuntime( 2049):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 2049):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.main(ActivityThread.java:4203)
E/AndroidRuntime( 2049):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2049):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 2049):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
E/AndroidRuntime( 2049):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
E/AndroidRuntime( 2049):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 2049): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049):    at android.view.ViewRoot.setView(ViewRoot.java:460)
E/AndroidRuntime( 2049):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime( 2049):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 2049):    at android.app.Dialog.show(Dialog.java:238)
E/AndroidRuntime( 2049):    at android.app.ProgressDialog.show(ProgressDialog.java:107)
E/AndroidRuntime( 2049):    at android.app.ProgressDialog.show(ProgressDialog.java:90)
E/AndroidRuntime( 2049):    at com.tastekid.TasteKid.YouTube.onCreate(YouTube.java:45)
E/AndroidRuntime( 2049):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
E/AndroidRuntime( 2049):    ... 11 more

कोई अंदाजा ऐसा क्यों हो रहा है? मैं इसे onCreateविधि से बुला रहा हूं ।


यदि आप उपयोग कर रहे हैं Fragment, तो stackoverflow.com/questions/24825114/…
Yeo

जवाबों:


42

आप किस एपीआई संस्करण का उपयोग कर रहे हैं? यदि मैं इस बारे में सही हूं कि समस्या क्या है तो यह एंड्रॉइड 1.6 (एपीआई संस्करण 4) में तय किया गया था।

यह ऑब्जेक्ट संदर्भ की तरह दिखता है जो getApplicationContext()केवल बिंदुओं को वापस कर रहा है। मुझे लगता है कि आप एक समस्या के समान हैं जो मेरे पास था जिसमें कुछ कोड में onCreate()चलाया जा रहा है इससे पहले कि खिड़की वास्तव में बनाई जा रही है। यह एक हैक होने जा रहा है, लेकिन कुछ सौ मिलीसेकंड (IIRC: 300-400 में मेरे लिए काम करने के लिए एक नया थ्रेड लॉन्च करने की कोशिश करें, लेकिन आपको टिंकर करने की आवश्यकता होगी) जो आपके प्रोग्रेसडियोग्ल को खोलता है और आपको जो कुछ भी चाहिए वह शुरू करता है ( उदा। नेटवर्क IO)। कुछ इस तरह:

@Override
public void onCreate(Bundle savedInstanceState) {
    // do all your other stuff here

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mProgressDialog = ProgressDialog.show(
               YouTube.this.getApplicationContext(), "",
               YouTube.this.getString(R.string.loading), true);

            // start time consuming background process here
        }
    }, 1000); // starting it in 1 second
}

6
मैं 1.6 का उपयोग कर रहा हूं। मुझे पूरा यकीन है कि किसी भी UI ऑपरेशन को यूआई थ्रेड में किया जाना चाहिए, इस प्रकार एक अलग थ्रेड में ProgressDialog.show () को कॉल करना आसानी से एक बड़ी समस्या हो सकती है। अब भी लगता है कि यह अजीब है।
फेलिक्स

3
उदाहरण में, मैंने आपको एक और धागे में यूआई ऑपरेशन नहीं किया है, दूसरा धागा यूआई थ्रेड को वापस बुला रहा है, यह संवाद खोलने के लिए कह रहा है।
जेरेमी लोगान

यह निश्चित रूप से अजीब है और यह कुल हैक है, लेकिन इसने मेरे लिए काम किया। मुझे बग का परीक्षण करने की आवश्यकता है जो मैं 1.6 में देख रहा था कि क्या मैं इसका उपयोग कर सकता हूं।
जेरेमी लोगान

1
यह 'अजीब' नहीं है और न ही यह 'कुल हैक' है, यह पूरी तरह से वैध दृष्टिकोण है!
कोमोडोवेव

1
@ कोमोडोवेव मुझे एहसास हुआ कि मुझे भी यही समस्या है। हालांकि, खराब हैक टाइमर में है। यह एक समयबद्ध खिड़की है जो कुछ स्थितियों में रुक-रुक कर आने की प्रतीक्षा कर रही है। सफलता की कुंजी एक छोटे टाइमर को सेट करने में हो सकती है, यह देखने के लिए जांचें कि क्या एप्लिकेशन तैयार है, जब तक यह है तब तक कार्रवाई फिर से करें। संभवत: कितनी बार प्रयास करें।
जिम रश

129

मैं एपीआई स्तर 7. के साथ एंड्रॉइड संस्करण 2.1 का उपयोग कर रहा हूं। मुझे इस (या समान) समस्या का सामना करना पड़ा और इसका उपयोग करके हल किया गया:

Dialog dialog = new Dialog(this);

इसके अलावा:

Dialog dialog = new Dialog(getApplicationContext());

उम्मीद है की यह मदद करेगा :)


4
मेरे पास एक समान मुद्दा था, लेकिन एक गतिविधि समूह का उपयोग कर रहा था। इस त्रुटि को हल करने का एकमात्र तरीका मैं getParent () के बजाय उपयोग कर रहा था।
दिसबंर को

20
यह उसके प्रश्न का उत्तर कैसे देता है? वह पूछता है कि दूसरा काम क्यों नहीं करता है, जबकि पहला काम करता है।
बुर्खर्ड

3
-1, 'यह' हम में से कुछ के लिए 'getApplicationContext ()' के समान है।
kellogs

फिर भी 2.1 के लिए एक उपयोगी टिप विकसित हो रही है
कार्लोस पी

64

मेरे लिए बदलाव का काम किया

builder = new AlertDialog.Builder(getApplicationContext());

सेवा

builder = new AlertDialog.Builder(ThisActivityClassName.this);

अजीब बात यह है कि पहले एक को Google ट्यूटोरियल में पाया जा सकता है और लोगों को इस पर त्रुटि मिलती है ।।


1
एकमात्र समाधान एक ऑनक्लिक ईवेंट के अंदर एक चेतावनी के साथ मेरे लिए काम
टोबियास

यह इसे करने का सही तरीका है। ApplicationContext का उपयोग तब तक न करें जब तक कि कड़ाई से आवश्यक और सभी से ऊपर, यूआई तत्वों को प्रदर्शित करने के लिए कभी भी इसका उपयोग न करें। यही गतिविधियाँ (और अंततः टुकड़े) हैं।
मार्टिन मार्कोसिनी

यही तो है वो। thisयदि आप ऐसा कर रहे हैं तो सभी अकेले काम नहीं करेंगे, उदाहरण के लिए, श्रोता पर क्लिक करें।
अयमान सला

23

मुझे नहीं लगता कि यह एक अशक्त अनुप्रयोग के संदर्भ में समय का मुद्दा है

अपने ऐप के भीतर एप्लिकेशन को विस्तारित करने का प्रयास करें (या यदि आपके पास पहले से है तो इसका उपयोग करें)

public class MyApp extends Application

उदाहरण के लिए एक निजी एकल के रूप में उपलब्ध कराएँ। यह कभी भी अशक्त नहीं है

private static MyApp appInstance;

MyApp में एक स्थिर सहायक बनाएं (जो सिंगलटन का उपयोग करेगा)

    public static void showProgressDialog( CharSequence title, CharSequence message )
{
    prog = ProgressDialog.show(appInstance, title, message, true); // Never Do This!
}

बूम !!

इसके अलावा, यहां Android इंजीनियर के जवाब की जांच करें: WindowManager $ BadTokenException

इस त्रुटि का एक कारण एक कॉन्सेप्ट के माध्यम से एप्लिकेशन विंडो / संवाद को प्रदर्शित करने की कोशिश हो सकती है जो एक गतिविधि नहीं है।

अब, मैं सहमत हूं, इसका मतलब यह नहीं है कि यह गतिविधि गतिविधि के बजाय एक संदर्भ पैरामेट लेती है।


10

उपर्युक्त उत्तरों को पढ़ने के बाद मैंने पाया कि मेरी स्थिति के लिए निम्नलिखित समस्या का समाधान हो गया है।

इसने त्रुटि को फेंक दिया

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(getApplicationContext());
        dialog.show();              
    }
});

संदर्भ का सुझाव देने वाले पिछले उत्तरों के आधार पर यह गलत था, मैंने getApplicationContext () को संदर्भ को पुनः प्राप्त करने के लिए बटन पर क्लिक किए गए बटन पर क्लिक करके बदल दिया।

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(v.getContext());
        dialog.show();              
    }
});

मैं जावा के कामकाज को पूरी तरह से नहीं समझता हूं, इसलिए मैं गलत हो सकता हूं, लेकिन मैं अनुमान लगा रहा हूं कि मेरी विशिष्ट स्थिति के लिए कारण इस तथ्य से संबंधित हो सकता है कि उपरोक्त स्निपेट को सार गतिविधि वर्ग में परिभाषित किया गया था; विरासत में मिली और कई गतिविधियों द्वारा उपयोग की गई, शायद इस तथ्य में योगदान दिया कि getApplicationContext () एक वैध संदर्भ वापस नहीं करता है ?? (केवल अनुमान है)।


बेहतर स्कोर किए गए समाधान संभवतः अधिकांश मामलों के लिए काम करते हैं, लेकिन आपका v.getContext () तकनीक मेरा जैसे सबसे जिद्दी मामलों को हल करने के लिए लगता है। मेरा अनुभवजन्य जावा ज्ञान मुझे यह सोचने के लिए प्रेरित करता है कि एक ऑनक्रीट विधि से आने वाला एक संदर्भ बिल्कुल वैसा ही नहीं है जैसा कि व्यू ऑफ ऑनक्लिक विधि से आता है। पक्ष में मत देना!
जोश

इससे मेरा दिन बच गया!
एलेजांद्रो लुएंगो

6

मैं आइटम के ओवरले के साथ एक मानचित्र दृश्य बना रहा हूं। मैं अपने मानचित्रकारिता से इस तरह अपना आइटम आकार ले रहा था:

OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);

मैंने पाया कि मुझे "android.view.WindowManager $ BadTokenException मिलेगा: विंडो जोड़ने में असमर्थ - टोकन नल अनुप्रयोग के लिए नहीं है" अपवाद जब मेरा आइटमाइज़रओवर का ऑनपैप तरीका चालू हो गया था (जब स्थान मैपव्यू पर टैप किया गया है)।

मैंने पाया कि अगर मैं बस अपने कंस्ट्रक्टर को 'getApplicationContext ()' के बजाय 'यह' पास कर देता हूं, तो समस्या दूर हो गई। यह एलियनजैजैट के निष्कर्ष का समर्थन करता है। अजीब।


1
धन्यवाद, यह वास्तव में मेरा मुद्दा क्या था।
कोन

4

TabActivities के भीतर दिखाए गए कार्यों के लिए getParent () का उपयोग करें

final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

के बजाय

final AlertDialog.Builder builder = new AlertDialog.Builder(this);

3

Android 2.2 के
लिए इस कोड का उपयोग करें:

//activity is an instance of a class which extends android.app.Activity
Dialog dialog = new Dialog(activity);

इस कोड के बजाय:

// this code produces an ERROR:
//android.view.WindowManager$BadTokenException: 
//Unable to add window -- token null is not for an application
Context mContext = activity.getApplicationContext();
Dialog dialog = new Dialog(mContext);

टिप्पणी: मेरा कस्टम संवाद बाहर की activity.onCreateDialog(int dialogId)विधि से बना है।


3

प्रयत्न -

AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

जरूरत है जब वर्तमान गतिविधि एक गतिविधि समूह के अंदर हो
htafoya

2

(संगतता) फ़्रैगमेंट के साथ एक समान समस्या थी, जिसके getActivity()भीतर एक ProgressDialog.show()दुर्घटनाग्रस्त हो गया। मैं मानता हूँ कि यह समय के कारण है।

एक संभावित फिक्स:

mContext = getApplicationContext();

if (mContext != null) {
    mProgressDialog = ProgressDialog.show(mContext, "", getString(R.string.loading), true);
}

के बजाय का उपयोग करने का

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

प्रसंग को हड़पने के लिए अधिक समय देने के लिए जितनी जल्दी हो सके mContext को रखें। अभी भी कोई गारंटी नहीं है कि यह काम करेगा, यह बस दुर्घटना की संभावना को कम करता है। यदि यह अभी भी काम नहीं करता है, तो आपको टाइमर हैक का सहारा लेना होगा (जो बाद में संवाद को खारिज करने जैसी अन्य समय समस्याओं का कारण बन सकता है)।

बेशक, यदि आप उपयोग कर सकते हैं thisया ActivityName.this, यह अधिक स्थिर है क्योंकि thisपहले से ही कुछ को इंगित करता है। लेकिन कुछ मामलों में, जैसे कुछ फ्रैगमेंट आर्किटेक्चर के साथ, यह एक विकल्प नहीं है।


2

(संदर्भ के लिए)

मुझे लगता है कि यह इसलिए है क्योंकि यहाँ पर समझाए गए अनुप्रयोग संदर्भ और गतिविधि के संदर्भ में मतभेद हैं: http://www.doubleencore.com/2013/06/ccxtxt/

जिसका अर्थ है कि हम एप्लिकेशन संदर्भ का उपयोग करके संवाद नहीं दिखा सकते हैं। बस।


2

गतिविधियों के अंदर संवाद का उपयोग करने के लिए, इसे इस तरह से करें:

private Context mContext;
private AlertDialog.Builder mBuilder;

@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     mContext = this;

     //using mContext here refering to activity context
     mBuilder = new AlertDialog.Builder(mContext);
     //...
     //rest of the code
     //...
}

टुकड़ों के अंदर संवाद का उपयोग करने के लिए, इसे इस तरह से करें:

private Context mContext;
private AlertDialog.Builder mBuilder;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View mRootView = inflater.inflate(R.layout.fragment_layout, container, false);
      mContext = getActivity();

      //using mContext here refering to fragment's hosting activity context
      mBuilder = new AlertDialog.Builder(mContext);
      //...
      //rest of the code
      //...
      return mRootView;
}

यह ^ _ ^ है


1

इसके लिए मैंने जो कुछ भी किया, वह था कि मैं अपनी सभी गतिविधियों के लिए एक बेस क्लास बनाऊं जहाँ मैं वैश्विक डेटा स्टोर करूँ। पहली गतिविधि में, मैंने अपने बेस क्लास में एक चर में संदर्भ को इस तरह बचाया:

बेस क्लास

public static Context myucontext; 

बेस क्लास से प्राप्त पहली गतिविधि

mycontext = this

तब मैं डायलॉग बनाते समय getApplicationContext के बजाय mycontext का उपयोग करता हूं।

AlertDialog alertDialog = new AlertDialog.Builder(mycontext).create();

शर्म आती है कि इस समाधान को कोई अधिक वोट नहीं मिलते हैं। यहां प्रस्तुत सभी संभावित समाधानों में से, यह केवल एक चीज है जो मेरे लिए एक AsyncTask में काम किया है
ckn

1

यदि आप एक खंड में ProgressDialog.show () कॉल कर रहे हैं, तो गतिविधि के लिए mContext कास्टिंग मेरे लिए काम कर रहा है।

     ProgressDialog pd = new ProgressDialog((Activity) mContext);

1

यह एक आम समस्या है। thisइसके बजाय का उपयोग करें getApplicationContext() कि आपकी समस्या को हल करना चाहिए


0

मैंने वर्तमान सक्रियता पर फेंकने के अपवाद के लिए अलर्ट डायलॉग लागू किया है। जब भी मैंने इस तरह दिया था

AlertDialog.Builder builder = new AlertDialog.Builder(context);

समान विंडो अपवाद को देखते हुए। मैं onCreate से अलर्ट के लिए कोड लिखता हूं ()। इसलिए मैंने पद्धति में कथन के context = this;बाद उपयोग किया। वैश्विक रूप से संदर्भ चर बनाएं।setContentView()onCreate()Context context;

कोड नमूना है

static Context context;

 public void onCreate(Bundle savedInstanceState)  { 
        super.onCreate(savedInstanceState); 


        setContentView(R.layout.network); 
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        context = this;
.......

अलर्ट विधि नमूना है

private void alertException(String execMsg){
        Log.i(TAG,"in alertException()..."+context);
        Log.e(TAG,"Exception :"+execMsg);
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
.......

यह मेरे लिए ठीक काम करता है। आमतौर पर मैंने StackOverflow पर इस त्रुटि के लिए खोजा। मुझे यह क्वेरी मिली। इस पोस्ट की सभी प्रतिक्रियाओं को पढ़ने के बाद, मैंने इस तरह से कोशिश की, इसलिए यह काम करता है। मैंने सोचा कि यह अपवाद को दूर करने के लिए एक सरल उपाय है।

धन्यवाद, राजेन्द्र


0

यदि आपके पास groupActivity पर कोई समस्या है तो इसका उपयोग न करें। पेरेंट पैरेंट एक्टिविटी ग्रुप से एक स्टैटिक है।

final AlertDialog.Builder builder = new AlertDialog.Builder(GroupActivityParent.PARENT);

के बजाय

final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.