Android 1.6: "android.view.WindowManager $ BadTokenException: विंडो जोड़ने में असमर्थ - टोकन नल अनुप्रयोग के लिए नहीं है"


303

मैं एक डायलॉग विंडो खोलने की कोशिश कर रहा हूं, लेकिन हर बार जब मैं इसे खोलने की कोशिश करता हूं तो यह अपवाद फेंकता है:

Uncaught handler: thread main exiting due to uncaught exception
android.view.WindowManager$BadTokenException: 
     Unable to add window -- token null is not for an application
  at android.view.ViewRoot.setView(ViewRoot.java:460)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
  at android.app.Dialog.show(Dialog.java:238)
  at android.app.Activity.showDialog(Activity.java:2413)

मैं इसे showDialogडिस्प्ले की आईडी से कॉल करके बना रहा हूं । onCreateDialogहैंडलर ठीक लॉग करता है और मैं इसे माध्यम से एक मुद्दा बिना कदम कर सकते हैं, लेकिन मैं इसे संलग्न किया है के बाद से ऐसा लगता है कि मैं कुछ याद कर रहा हूँ:

@Override
public Dialog onCreateDialog(int id)
{
    Dialog dialog;
    Context appContext = this.getApplicationContext();
    switch(id)
    {
        case RENAME_DIALOG_ID:
            Log.i("Edit", "Creating rename dialog...");
            dialog = new Dialog(appContext);
            dialog.setContentView(R.layout.rename);
            dialog.setTitle("Rename " + noteName);
            break;
        default:
            dialog = null;
            break;
    }
    return dialog;      
}

क्या इसमें से कुछ गायब है? कुछ प्रश्नों ने संवाद बनाते समय इस समस्या के होने के बारे में बात की है onCreate, जो इसलिए होता है क्योंकि गतिविधि अभी तक नहीं बनी है, लेकिन यह एक मेनू ऑब्जेक्ट से कॉल से आ रहा है, और appContextचर ऐसा लगता है जैसे यह डिबगर में सही ढंग से आबादी है।

जवाबों:


609

इसके बजाय: Context appContext = this.getApplicationContext(); आपको (संभवत:) उस गतिविधि के लिए एक सूचक का उपयोग करना चाहिए this

मुझे आज भी इस बात का सामना करना पड़ा है, कष्टप्रद हिस्सा getApplicationContext()डेवलपर.android.com से शब्दशः है :(


2
इसे एक बग के रूप में भी सूचित किया गया है (हालांकि यह तब नहीं था जब उपयोगकर्ता ने प्रश्न पोस्ट किया था): code.google.com/p/android/issues/detail?id=11199
रेमंड मार्टिन्यू

63
बस इस मामले में किसी को भी मदद करता है - एक संवाद में अपने संदर्भ के रूप में myActivity.this का उपयोग करें।
रब रॉस

13
यह सवाल और जवाब 2 दिन में 3 साल पुराना हो जाता है। मुझे अभी भी प्रतिष्ठा मिल रही है, इसलिए मुझे लगता है कि Google ने अभी भी अपने डॉक्स तय नहीं किए हैं ...
Torp


6
यह 2016 का अप्रैल है, और अभी भी यह अपवाद संवाद दीक्षा पर आवेदन दुर्घटना बना रहा है।
योगेश सेरलिया

78

आप एक ऐसी गतिविधि के माध्यम से एक एप्लिकेशन विंडो / संवाद प्रदर्शित नहीं कर सकते जो गतिविधि नहीं है। एक मान्य गतिविधि संदर्भ पास करने का प्रयास करें


कैसे? मैंने कोशिश की activity.thisऔर activity.getBaseContext()कोई फायदा नहीं हुआ। कोई मदद?
डारपॉन

3
समझ गया। इसमें सीधे अपनी गतिविधि का नाम दें। बिना .this
दरपन

45

Ditto getApplicationContext चीज़ पर।

एंड्रॉइड साइट पर दस्तावेज़ इसका उपयोग करने के लिए कहते हैं, लेकिन यह काम नहीं करता है ... grrrrr :-P

बस करो:

dialog = new Dialog(this); 

"यह" आमतौर पर आपकी गतिविधि है जिसमें से आप संवाद शुरू करते हैं।


43

Android दस्तावेज़ getApplicationContext () का उपयोग करने का सुझाव देते हैं;

लेकिन यह इसके बजाय काम नहीं करेगा कि AlertDialog.Builder या AlertDialog या Dialogating करते समय अपनी वर्तमान गतिविधि का उपयोग करें ...

उदाहरण के लिए:

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

या

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);

इससे मुझे बड़े पैमाने पर मदद मिली। मैं एक और संवाद के भीतर से एक संवाद बनाने की कोशिश कर रहा था और "AlertDialog.Builder (यह)?"; एक त्रुटि दे रहा था। धन्यवाद!
एह्रफाम

(ActivityName.this) एक बटन के अंदर एक संवाद बनाने की कोशिश करते समय विशेष रूप से उपयोगी है
RmK

मेरी समस्या यह है कि मैं एक Adapter के अंदर एक AlertDialog के अंदर एक ProgressDialog का निर्माण कर रहा हूँ ... मुझे यह काम करने के लिए नहीं मिल सकता है।
मार्टिन एरिक


13

मेरे पास एक समान मुद्दा था जहां मेरे पास एक और वर्ग कुछ इस तरह था:

public class Something {
  MyActivity myActivity;

  public Something(MyActivity myActivity) {
    this.myActivity=myActivity;
  }

  public void someMethod() {
   .
   .
   AlertDialog.Builder builder = new AlertDialog.Builder(myActivity);
   .
   AlertDialog alert = builder.create();
   alert.show();
  }
}

अधिकांश समय ठीक काम किया, लेकिन कभी-कभी यह एक ही त्रुटि के साथ दुर्घटनाग्रस्त हो गया। तब मुझे एहसास होता है कि MyActivityमैंने ...

public class MyActivity extends Activity {
  public static Something something;

  public void someMethod() {
    if (something==null) {
      something=new Something(this);
    }
  }
}

क्योंकि मैं ऑब्जेक्ट को पकड़ रहा था static, कोड का एक दूसरा रन अभी भी ऑब्जेक्ट के मूल संस्करण को पकड़ रहा था , और इस तरह अभी भी मूल का उल्लेख कर रहा था Activity, जो लंबे समय तक अस्तित्व में नहीं था।

मूर्खतापूर्ण गलती, खासकर के रूप में मैं वास्तव staticमें पहली जगह के रूप में वस्तु धारण करने की जरूरत नहीं थी ...


12

बस इसे में बदलें

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(YourActivity.this);

के बजाय

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

9

एक अन्य समाधान एक सिस्टम संवाद में विंडो प्रकार सेट करना है:

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

इसके लिए SYSTEM_ALERT_WINDOWअनुमति चाहिए :

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

डॉक्स कहते हैं:

बहुत कम अनुप्रयोगों को इस अनुमति का उपयोग करना चाहिए; ये विंडो उपयोगकर्ता के साथ सिस्टम-स्तरीय इंटरैक्शन के लिए अभिप्रेत हैं।

यह एक ऐसा समाधान है जिसका आपको केवल तभी उपयोग करना चाहिए जब आपको एक ऐसे संवाद की आवश्यकता हो जो किसी गतिविधि से जुड़ा न हो।


यह अब एपीआई स्तर 26 से चिह्नित ध्वज है। क्योंकि यह डेवलपर को सिस्टम विंडो के साथ खेलने की अनुमति देता है जो उपयोगकर्ता के दृष्टिकोण से अच्छा नहीं है।
CopsOnRoad

4

getApplicationContext()डायलॉग घोषित करने पर उपयोग न करें

हमेशा उपयोग thisया अपनेactivity.this


2

नेस्टेड संवादों के लिए यह मुद्दा बहुत आम है, यह कब काम करता है

AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);

के बजाय प्रयोग किया जाता है

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

यह विकल्प है।


2

यह मेरे लिए काम किया -

new AlertDialog.Builder(MainActivity.this)
        .setMessage(Html.fromHtml("<b><i><u>Spread Knowledge Unto The Last</u></i></b>"))
        .setCancelable(false)
        .setPositiveButton("Dismiss",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                    }
                }).show();

उपयोग

ActivityName.this

0

आप यह भी कर सकते हैं

public class Example extends Activity {
    final Context context = this;
    final Dialog dialog = new Dialog(context);
}

यह मेरे लिए काम किया !!


0

जैसा कि कहा गया है, आपको संवाद के लिए संदर्भ के रूप में एक गतिविधि की आवश्यकता है, एक स्थिर संदर्भ के लिए "YourActivity.this" का उपयोग करें या एक सुरक्षित मोड में एक गतिशील एक का उपयोग करने के तरीके के लिए यहां जांचें


0

dialogविंडो के प्रकार को रीसेट करने का प्रयास करें

WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

अनुमति का उपयोग करने के लिए मत भूलना android.permission.SYSTEM_ALERT_WINDOW


0
public class Splash extends Activity {

    Location location;
    LocationManager locationManager;
    LocationListener locationlistener;
    ImageView image_view;
    ublic static ProgressDialog progressdialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);
        progressdialog = new ProgressDialog(Splash.this);
           image_view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                        locationManager.requestLocationUpdates("gps", 100000, 1, locationlistener);
                        Toast.makeText(getApplicationContext(), "Getting Location plz wait...", Toast.LENGTH_SHORT).show();

                            progressdialog.setMessage("getting Location");
                            progressdialog.show();
                            Intent intent = new Intent(Splash.this,Show_LatLng.class);
//                          }
        });
    }

यहां पाठ: - के
लिए activityसंदर्भ प्राप्त करने के लिए इसका उपयोग करेंprogressdialog

 progressdialog = new ProgressDialog(Splash.this);

या progressdialog = new ProgressDialog(this);

BroadcastListener नहीं के लिए आवेदन संदर्भ प्राप्त करने के लिए इसका उपयोग करें progressdialog

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());

0

AsyncTask में 'ProgressDialog' दिखाने का सबसे अच्छा और सुरक्षित तरीका, मेमोरी लीक की समस्या से बचना है, Looper.main () के साथ 'हैंडलर' का उपयोग करना है।

    private ProgressDialog tProgressDialog;

फिर 'ऑनक्रिएट' में

    tProgressDialog = new ProgressDialog(this);
    tProgressDialog.setMessage(getString(R.string.loading));
    tProgressDialog.setIndeterminate(true);

अब आपने सेटअप भाग के साथ आर किया। अब AsyncTask में 'showProgress ()' और 'hideProgress ()' को कॉल करें।

    private void showProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.show();
            }
        }.sendEmptyMessage(1);
    }

    private void hideProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.dismiss();
            }
        }.sendEmptyMessage(1);
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.