Android 1.6: “android.view.WindowManager $ BadTokenException: Impossibile aggiungere finestra - nulla pedina non è per un'applicazione”
-
26-09-2019 - |
Domanda
Sto cercando di aprire una finestra di dialogo, ma ogni volta che provo ad aprirlo che genera questa eccezione:
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)
Sto creando chiamando showDialog
con id del display. Il gestore onCreateDialog
registra bene e mi può fare un passo attraverso di essa, senza un problema, ma ho attaccato esso in quanto sembra che mi manca qualcosa:
@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;
}
C'è qualcosa che manca da questo? Alcune domande hanno parlato di avere questo problema quando si crea una finestra di dialogo da onCreate
, che avviene perché l'attività non è ancora creata, ma questo viene da una chiamata da un oggetto menu, e la variabile appContext
sembra che sia correttamente popolato nel debugger.
Soluzione
Al posto di:
Context appContext = this.getApplicationContext();
si dovrebbe usare un puntatore per l'attività si è in (probabilmente this
).
mi sono morso da questo anche oggi, la parte fastidiosa è la getApplicationContext()
è pari pari da developer.android.com: (
Altri suggerimenti
Non è possibile visualizzare una finestra / finestra di dialogo dell'applicazione attraverso un contesto che non è un'attività. Prova a passare un riferimento un'attività valida
Idem sulla cosa getApplicationContext.
I documenti sul sito Android dice di usarlo, ma non funziona ... :-P grrrrr
Basta fare:
dialog = new Dialog(this);
"questo" è di solito la tua attività da cui si avvia la finestra di dialogo.
documenti Android suggerisce di utilizzare getApplicationContext ();
, ma non funzionerà invece che l'uso vostra attività in corso, mentre un'istanza AlertDialog.Builder o AlertDialog o Dialog ...
Esempio:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
o
AlertDialog.Builder builder = new AlertDialog.Builder((Your Activity).this);
Invece di getApplicationContext()
, basta usare ActivityName.this
Ho avuto un problema simile in cui ho avuto un'altra classe qualcosa di simile:
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();
}
}
multa lavorato la maggior parte del tempo, ma a volte si è schiantato con lo stesso errore. Poi mi rendo conto che in MyActivity
ho avuto ...
public class MyActivity extends Activity {
public static Something something;
public void someMethod() {
if (something==null) {
something=new Something(this);
}
}
}
Perché avevo in mano l'oggetto come static
, una seconda esecuzione del codice è stato ancora in mano la versione originale dell'oggetto, e quindi era ancora riferiva al Activity
originale, che non esiste da molto tempo.
sciocco stupido errore, soprattutto perché io davvero non aveva bisogno di essere tenuta l'oggetto come static
in primo luogo ...
Basta cambiare in
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(YourActivity.this);
Al posto di
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(getApplicationContext());
Un'altra soluzione è quella di impostare il tipo di finestra per una finestra di sistema:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Ciò richiede l'href="http://developer.android.com/reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW"> Per quanto i documenti dicono: Molto poche applicazioni dovrebbe usare questa autorizzazione; queste finestre sono destinati per l'interazione a livello di sistema con l'utente. Questa è una soluzione si dovrebbe usare solo se avete bisogno di un dialogo che non è collegato a un'attività. SYSTEM_ALERT_WINDOW
permesso <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Non utilizzare getApplicationContext()
sulla proclamazione del dialouge
Sempre uso this
o il vostro activity.this
Questo ha funzionato per me -
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();
Usa
ActivityName.this
Per le finestre di dialogo nidificate questo problema è molto comune, Funziona quando
AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);
è usato al posto di
mDialogBuilder = new AlertDialog.Builder(getApplicationContext);
questa alternativa.
È anche possibile fare questo
public class Example extends Activity {
final Context context = this;
final Dialog dialog = new Dialog(context);
}
Questo ha funzionato per me !!
Come si dice, è necessario un contesto di attività, come per la finestra, usa "YourActivity.this" per un contesto statico o controllare qui per come utilizzare una dinamica in una modalità sicura
Prova a ripristinare il tipo di finestra dialog
a
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Non dimenticare di utilizzare il android.permission.SYSTEM_ALERT_WINDOW
autorizzazione
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);
// }
});
}
Testo qui: -
utilizzare questo per ottenere contesto activity
per progressdialog
progressdialog = new ProgressDialog(Splash.this);
o progressdialog = new ProgressDialog(this);
utilizzare questo per ottenere il contesto applicativo per BroadcastListener
non per progressdialog
.
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
Il meglio e il modo più sicuro per mostrare un 'ProgressDialog' in un AsyncTask, evitando problemi di perdita di memoria è di utilizzare un 'Handler' con Looper.main ().
private ProgressDialog tProgressDialog;
poi nel 'onCreate'
tProgressDialog = new ProgressDialog(this);
tProgressDialog.setMessage(getString(R.string.loading));
tProgressDialog.setIndeterminate(true);
Ora si r fatto con la parte di installazione. Ora chiamare 'showProgress ()' e 'hideProgress ()' in AsyncTask.
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);
}