Android Wieso geht getApplicationContext() bei Toast, aber nicht bei AlertDialog.Builder?

W

Windows10

Bekanntes Mitglied
Ich habe über MainActivity eine weitere Activity über ein Intent gestartet.
Java:
Intent intent=new Intent(this, NewFilmActivity.class);

startActivityForResult(intent, 1);
Dieser Code funktioniert.

Wenn ich in dieser Activity jetzt aber folgede zwei Sachen mit einem AlertDilaog.Builder ausführe, klappt es nicht.
Java:
 private AlertDialog.Builder showAlertDialog(String s, String neutral)
    {
       return new AlertDialog.Builder(this)
                .setCancelable(false)
                .setIcon(android.R.drawable.ic_dialog_info)
                .setMessage(s)
                .setNeutralButton(neutral, null);
    }
oder
Java:
 private AlertDialog.Builder showAlertDialog(String s, String neutral)
    {
       return new AlertDialog.Builder(getApplicationContext())
                .setCancelable(false)
                .setIcon(android.R.drawable.ic_dialog_info)
                .setMessage(s)
                .setNeutralButton(neutral, null);
    }

Bei Toast würde es aber klappen

Java:
Toast.makeText(getApplicationContext(), "Hallo", Toast.LENGTH_LONG).show();
Also wieso klappt getApplicationContext() bei Toast schon aber bei AlertDialog.Builder nicht?
 
kneitzel

kneitzel

Top Contributor
Kannst Du noch Details nennen, was für einen Fehler du bekommst? Fehler / Exception mit Stacktrace und so können immer bei der Fehlersuche weiter helfen.
 
W

Windows10

Bekanntes Mitglied
Kann es aber schon auf das beschriebene Problem oben beschränken (AlertDialog.Builder), da der Fehler immer im Zusammenhang mit dem AlertDialog.Builder auftritt.
 

Anhänge

  • 1591639947986.png
    1591639947986.png
    326,1 KB · Aufrufe: 15
kneitzel

kneitzel

Top Contributor
Bitte sowas nicht als Bildschirmfoto sondern in Code Tags posten. Dann ist es deutlich besser.

Und dann zeig mal den Code, wann Du das überhaupt aufrufst? Kann es sein, dass die Activity schon beendet wurde, wenn Du das aufrufst? Das wäre dann eine Erklärung für diese Exception (siehe z.B. https://stackoverflow.com/questions/2850573/activity-has-leaked-window-that-was-originally-added) Beachte die Erläuterungen dazu: Die Activity könnte z.B. durch eine Exception schon beendet worden sein z.b. in einem Async Task oder so!

Also bitte bring mehr: Das was Du hier bringst ist aus meiner Sicht für eine Fehlersuche nicht ausreichend.
 
W

Windows10

Bekanntes Mitglied
Der gesamte Code der Klasse mit dem Fehler:
Java:
package htl.grieskirchen.pos.android.filmapp;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;

import java.util.concurrent.ExecutionException;

public class NewFilmActivity extends AppCompatActivity {
    private Spinner status;
    private Button anlegen;
    private EditText title;
    private Film film;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_film);
        this.status=findViewById(R.id.spinnerNewStatus);
        this.anlegen=findViewById(R.id.anlegenSuchen);
        this.title=findViewById(R.id.editFilm);
        Status[]statuses=Status.values();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, toStringArray(statuses));
        this.status.setAdapter(adapter);
        this.anlegen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               getFilm(v);
               Intent data = new Intent();
               data.putExtra("title", film.getName());
               data.putExtra("status", film.getStatus().toString());
               setResult(RESULT_OK, data);
               finish();
               }
        });
    }

    private String[] toStringArray(Status[] statuses) {
        String[]s=new String[statuses.length];
        for(int i=0;i<statuses.length;i++)
        {
            if(statuses[i]==Status.NICHTS)
            {
                s[i]=" ";
            }
            else {
                s[i] = statuses[i].toString();
            }
        }
        return s;
    }

    private void getFilm(View v)
    {
        String filmname=this.title.getText().toString();
        sucheFilm(filmname);
        if(film==null)
        {
            newFilmAnlegen(filmname);
            AlertDialog.Builder builder=showAlertDialog("Neuer Film wurde erfolgreich angelegt", "ok");
            builder.show();
        }
    }
    private void newFilmAnlegen(String s)
    {
        if(s.equals(""))
        {
            AlertDialog.Builder builder=showAlertDialog("Es wurde kein Film eingegeben! Hole es nach!  ", "ok");
            builder.show();
        }
        else if(this.status.getSelectedItem().toString().equals(""))
        {
            film=new Film(s);
        }
        else
        {
            film=new Film(s, Status.valueOf(this.status.getSelectedItem().toString()));
        }
    }
    private void sucheFilm(String s)
    {
        if(s.equals(""))
        {
            AlertDialog.Builder builder=showAlertDialog("Es wurde kein Film eingegeben! Hole es nach!  ", "ok");
            builder.show();
        }
        else if(loadDataFromInternet()!=null)
        {
         String json=loadDataFromInternet();
         if(json!=null) {
             AlertDialog.Builder builder = showAlertDialog("Film wurde in Datenbank gefunden. Willst du damit einen neuen Film anlegen?", "Abbrechen");
             builder.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
                 @Override
                 public void onClick(DialogInterface dialog, int which) {
                     //aus json filmname holen und daraus einen neuen Film erstellen und der Variable Film zuweisen
                 }
             });
             builder.show();
         }
         else
         {
             AlertDialog.Builder builder = showAlertDialog("Film wurde in Datenbank nicht gefunden. Willst du den Film selber anlgen?", "Abbrechen");
             builder.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
                 @Override
                 public void onClick(DialogInterface dialog, int which) {
                     Status stat=getSelectedStatus(status.getSelectedItem().toString());
                     String name=title.getText().toString();
                     if(stat != null)
                     {
                         film=new Film(name, stat);
                     }
                 }

                 private Status getSelectedStatus(String st) {
                     if(st.equals(" "))
                     {
                         st="NICHTS";
                     }
                     if(st.equals("NICHTS")||st.equals("WARTELISTE")||st.equals("GESEHEN"))
                     {
                         return Status.valueOf(st);
                     }
                     return null;
                 }
             });
             builder.show();
         }
        }
    }

    private AlertDialog.Builder showAlertDialog(String s, String neutral)
    {
       return new AlertDialog.Builder(getApplicationContext())
                .setCancelable(false)
                .setIcon(android.R.drawable.ic_dialog_info)
                .setMessage(s)
                .setNeutralButton(neutral, null);
    }

    private String loadDataFromInternet()
    {
        String json=null;
        String filmName=this.title.getText().toString();
        SearchTask searchTask=new SearchTask(getURL("%20", filmName.split(" "), "https://movie-database-imdb-alternative.p.rapidapi.com/?page=1&r=json&s="));
        AsyncTask<String, Integer, String> asyncTask=searchTask.execute();
        try {
            json = asyncTask.get();
        } catch (ExecutionException|InterruptedException e) {
            e.printStackTrace();
        }
        return json;
    }

    private String getURL(String trenn, String[] s, String link) {
        StringBuilder sb=new StringBuilder();
        sb.append(link);
        for(String st:s)
        {
            sb.append(st.trim());
            sb.append(trenn);
        }
        String st=sb.toString().trim();
        return st.substring(0, st.length()-2);
    }
}

Die StackOverflow Seite hab ich schon besucht, bevor ich diese Seite aufgesucht habe.
 
J

JennyL

Bekanntes Mitglied

Du musst "new AlertDialog.Builder(YourActivityClassName.this);" verwenden, nicht getApplicationContext() (wie beim Toast).
 
W

Windows10

Bekanntes Mitglied

Du musst "new AlertDialog.Builder(YourActivityClassName.this);" verwenden, nicht getApplicationContext() (wie beim Toast).
Das erzeugt aber ebenfalls genau den gleichen Fehler, hatte ich nämlich auch schon versucht
 
J

JennyL

Bekanntes Mitglied
Aha, du hast hoffentlich auch die richtige Klasse (NewFilmActivity.) eingesetzt?


(Du versuchst einen Dialog zu öffnen nachdem die Aktivität beendet wurde, deswegen tritt die Fehlermeldung auf)

Ansonsten ist es natürlich eine Frechheit, einen Screen vom Stacktrace zu machen anstatt ihn hier zu posten...
 
kneitzel

kneitzel

Top Contributor
Habe den Code jetzt nur so auf dem Handy überfliegen können ... das Problem tritt laut Stacktrace ja im getFilm auf und nicht im SucheFilm. Die Zeilennummern kann ich nicht zuordnen, aber kann es sein, dass der Dialog vom sucheFilm noch nicht richtig geschlossen ist, wenn du in getFilm den nächsten öffnen willst oder so?

Ist schwer so alles am Handy nach zu vollziehen. Morgen kann ich das evtl. am Rechner in Ruhe ansehen.

Evtl. kannst du in der Zwischenzeit den ausführlichen Stacktrace mal kopieren und in code Tags hier posten.

Und das Design verwirrt mich noch etwas. Du nutzt diese Dialoge massive. Da möchte ich nicht 'falsch' zu sagen, aber so kenne ich das bisher eher nicht ... aber ich bin bezüglich Android auch kein Profi da ich das eigentlich anderen überlasse.

Testweise kannst du ja mal Dialoge auskommentieren um zu schauen, ob du dann durch diese getFilm Methode kommst ...
 
W

Windows10

Bekanntes Mitglied
Habe den Code jetzt nur so auf dem Handy überfliegen können ... das Problem tritt laut Stacktrace ja im getFilm auf und nicht im SucheFilm. Die Zeilennummern kann ich nicht zuordnen, aber kann es sein, dass der Dialog vom sucheFilm noch nicht richtig geschlossen ist, wenn du in getFilm den nächsten öffnen willst oder so?

Ist schwer so alles am Handy nach zu vollziehen. Morgen kann ich das evtl. am Rechner in Ruhe ansehen.

Evtl. kannst du in der Zwischenzeit den ausführlichen Stacktrace mal kopieren und in code Tags hier posten.

Und das Design verwirrt mich noch etwas. Du nutzt diese Dialoge massive. Da möchte ich nicht 'falsch' zu sagen, aber so kenne ich das bisher eher nicht ... aber ich bin bezüglich Android auch kein Profi da ich das eigentlich anderen überlasse.

Testweise kannst du ja mal Dialoge auskommentieren um zu schauen, ob du dann durch diese getFilm Methode kommst ...
Das tritt bei jedem Dialog auf, deswegen kann ich auch nicht testweise welche auskommentieren, da es dann bei dem nächsten auftritt.
 
mihe7

mihe7

Top Contributor
Was passiert denn, wenn Du nur mal
Java:
    private AlertDialog.Builder showAlertDialog(String s, String neutral)
    {
       return new AlertDialog.Builder(this);
    }
verwendest?
 
kneitzel

kneitzel

Top Contributor
Das wundert mich jetzt. Da passen dann Dein Code und der Stacktrace nicht zusammen.

Laut Stacktrace ist es da der Aufruf in getFilm und um dahin zu kommen, muss er erst durch sucheFilm durch.
SucheFilm hat aber in allen Teilen bereits so einen Aufruf gehabt, also egal ob das erste if, das else if oder der else Block durchlaufen werden....

Oder habe ich da jetzt etwas übersehen?
 
kneitzel

kneitzel

Top Contributor
Das hat nichts mit Frechheit zu tun. Da zwischen seinen Posts etwas über eine Stunde liegt, wird er vermutlich etwas verändert haben. Oder die Problematik ist etwas anders, als er glaubt.

Wenn ich die Zeit finde, werde ich nachher noch ein paar kleine Tests machen um meine Hypothese etwas zu prüfen. Aber @mihe7 ist ja auch im Thread aktiv und er hat deutlich mehr Erfahrung mit Android, so dass der TE in guten Händen sein dürfte (so er auf Fragen antwortet und so).
 
mihe7

mihe7

Top Contributor
er hat deutlich mehr Erfahrung mit Android,
Das täuscht, bei mir verhält es sich wie bei Dir. In der Arbeit kümmern sich andere um die Apps, was die Programmierung dort betrifft, bin ich nur als letzte Instanz in Form des Problemlösers beteiligt :)

@Windows10 Jetzt habe ich das Poblem, glaube ich, gesehen. Im onClick wird getFilm aufgerufen, der Dialog wird angezeigt und am Ende von onClick ziehst Du dem Dialog mittels finish die Activity unter den Füßen weg.
 
kneitzel

kneitzel

Top Contributor
Das täuscht, bei mir verhält es sich wie bei Dir. In der Arbeit kümmern sich andere um die Apps, was die Programmierung dort betrifft, bin ich nur als letzte Instanz in Form des Problemlösers beteiligt :)

Ok, du bist der "Google Search Expert" und nicht der "Android Developer Expert" :)

@Windows10 Jetzt habe ich das Poblem, glaube ich, gesehen. Im onClick wird getFilm aufgerufen, der Dialog wird angezeigt und am Ende von onClick ziehst Du dem Dialog mittels finish die Activity unter den Füßen weg.

Ah. Das ist mir so gar nicht aufgefallen. Gut gesehen. Dann erspare ich es mir an dieser Stelle, da die Problematik mit zwei AlertDialogen hintereinander nachzustellen. Das was Du da gefunden hast klingt erst einmal deutlich plausibler.
 
W

Windows10

Bekanntes Mitglied
Was passiert denn, wenn Du nur mal
Java:
    private AlertDialog.Builder showAlertDialog(String s, String neutral)
    {
       return new AlertDialog.Builder(this);
    }
verwendest?

Das wundert mich jetzt. Da passen dann Dein Code und der Stacktrace nicht zusammen.

Laut Stacktrace ist es da der Aufruf in getFilm und um dahin zu kommen, muss er erst durch sucheFilm durch.
SucheFilm hat aber in allen Teilen bereits so einen Aufruf gehabt, also egal ob das erste if, das else if oder der else Block durchlaufen werden....

Oder habe ich da jetzt etwas übersehen?
Könnte so sein, dann weiß ich aber nicht, wie ich verhindere, dass ein Dialog aufgemacht wird, wenn gerade einer geöffnet ist, also angezeigt wird.
 
W

Windows10

Bekanntes Mitglied
Das täuscht, bei mir verhält es sich wie bei Dir. In der Arbeit kümmern sich andere um die Apps, was die Programmierung dort betrifft, bin ich nur als letzte Instanz in Form des Problemlösers beteiligt :)

@Windows10 Jetzt habe ich das Poblem, glaube ich, gesehen. Im onClick wird getFilm aufgerufen, der Dialog wird angezeigt und am Ende von onClick ziehst Du dem Dialog mittels finish die Activity unter den Füßen weg.
Ja, ist auch meine Vermutung, ich will aber die anderen Dialoge auch anzeigen in dieser Film Activity
 
W

Windows10

Bekanntes Mitglied
Du darfst aber die Activity nicht schließen, so lange Du den Dialog anzeigst.
Ist mir klar, weiß aber nicht wie ich das verhindere.

Hab nur eine Idee:

Die finish()-Methode nach dem show() vom AlertDialog schreiben.

Wenn ich aber einen Dialog aufmache und in der Zeit in der ein Dialog offen ist, wieder einen aufmache, wie kann ich das verhindern.
 
mihe7

mihe7

Top Contributor
Die finish-Methode wird bereits nach dem show() aufgerufen. Du musst halt auf das Schließen des Dialogs reagieren (setOnDismissListener).
 
W

Windows10

Bekanntes Mitglied
setOnDismissListener hat das Problem nicht behoben. Bekomme immer noch die gleiche Fehlermeldunng.

Habe folgenden Code geändert, der Rest blieb gleich:

Java:
 private AlertDialog.Builder showAlertDialog(String s, String neutral)
    {
       return new AlertDialog.Builder(NewFilmActivity.this)
               .setCancelable(false).setIcon(android.R.drawable.ic_dialog_info)
               .setMessage(s)
               .setNeutralButton(neutral, null)
               .setOnDismissListener(new DialogInterface.OnDismissListener() {
                   @Override
                   public void onDismiss(DialogInterface dialog) {

                   }
               });
    }
 
mihe7

mihe7

Top Contributor
Sieht Dein setOnClickListener so aus?
Java:
        this.anlegen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               getFilm(v);
               }
        });
 
W

Windows10

Bekanntes Mitglied
Sieht Dein setOnClickListener so aus?
Java:
        this.anlegen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               getFilm(v);
               }
        });
Habe das nicht geändert, sieht also so aus, wie in meinem Post, wo ich den ganzen Code dieser Klasse gepostet habe
 
mihe7

mihe7

Top Contributor
Ja, dann änder das so ab, und versuch es mal. Es geht erstmal darum, den Fehler weg zu bekommen.
 
W

Windows10

Bekanntes Mitglied
Jetzt sieht es so aus:

Java:
 this.anlegen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               getFilm(v);
//               Intent data = new Intent();
//               data.putExtra("title", film.getName());
//               data.putExtra("status", film.getStatus().toString());
//               setResult(RESULT_OK, data);
//               finish();
               }
        });
 
W

Windows10

Bekanntes Mitglied
Jetzt werden alle Dialoge (die ich will) ohne Fehler angezeigt.

Wo soll ich jetzt die auskommentierten Codeabschnitte ausführen? Nach onClick() vom Button anlegen?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Android Wieso kann ich keine ListView mehr zum Layout hinzufügen? Android & Cross-Platform Mobile Apps 1
A Wieso wird die App beendet ??? Android & Cross-Platform Mobile Apps 2
A Wieso keine java - forum app Android & Cross-Platform Mobile Apps 4
A Kann nicht in TextView einer anderen Klasse schreiben - wieso? Android & Cross-Platform Mobile Apps 9
K Log.v geht nicht Android & Cross-Platform Mobile Apps 4
J R.string.(variable) geht das Android & Cross-Platform Mobile Apps 3
B Timer geht nicht Android & Cross-Platform Mobile Apps 2
L Android Apache POI: Datei speichern geht nicht Android & Cross-Platform Mobile Apps 1
T Button geht net... Android & Cross-Platform Mobile Apps 2
D Hilfe! es geht um Buttons und Sounds Android & Cross-Platform Mobile Apps 14
S Android LogCat Ausgaben in Schleife geht nicht? Android & Cross-Platform Mobile Apps 2
K Android Alarm Manager (Wakelock? ) geht nicht Android & Cross-Platform Mobile Apps 4
N Android Hilfe string to float geht nicht... Android & Cross-Platform Mobile Apps 4
P Android Programm stürzt ab - Es geht um Netzwerk Android & Cross-Platform Mobile Apps 5
D wie geht Klassenvererbung von Canvas Klassen Android & Cross-Platform Mobile Apps 2
R Meine arctan-Methode geht nicht Android & Cross-Platform Mobile Apps 6
X Anfängerfrage : Form und CommandListener - Warum geht das nicht? Android & Cross-Platform Mobile Apps 5

Ähnliche Java Themen

Anzeige

Neue Themen


Oben