SharedPreferences werden nicht vollständig gelöscht

  • Antworten:27
yugox
  • Forum-Beiträge: 27

19.05.2018, 12:11:31 via Website

Hallo zusammen!

Ich habe ein Problem mit den SharedPreferences, ich verstehe nicht genau wieso die Werte nicht gelöscht werden.

Hier einmal der Code:

Intent NR 1

    private void btnBackFunction() {
        Intent intent = new Intent(this, MenuActivity.class);
        intent.putExtra("btnBack", true);
        startActivity(intent);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        finish();
}

Intent NR 2

    SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);
    SharedPreferences sprGameField = getSharedPreferences("XX", 0);

    Intent myIntent = getIntent();
    Boolean btnBack = myIntent.getBooleanExtra("btnBack", false);

    if(btnBack) {
        SharedPreferences.Editor eG = sprGameFieldSettings.edit();
        eG.clear();
        eG.commit();
        SharedPreferences.Editor eGF = sprGameField.edit();
        eGF.clear();
        eGF.commit();
    }

    if(sprGameFieldSettings.contains("breakGame")) {
        redirectMainActivity();
        return;
    }
}

private void redirectMainActivity() {
    Intent intent = new Intent(this, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btnStartAZ:
            SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);
            SharedPreferences.Editor eG = sprGameFieldSettings.edit();
            eG.putInt("difficulty", difficulty);
            eG.putInt("firstDimension", firstDimension);
            eG.putInt("secondDimension", secondDimension);
            eG.apply();

            Intent intent = new Intent(this, MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
            finish();
            break;

        default:
            break;
    }
}

Bei Button click "Back" wird die Funktion btnBackFunction() im 1. Intent aufgerufen dieser verweist auf das 2. Intent, dort sollten alle Werte gelöscht werden.

Wenn ich dann das Spiel neustarte "btnStartAZ",.dann sollen neue Werte eingetragen werden. Beim debuggen im Bereich " if(btnBack) " sind die Werte auch erstmal gelöscht, aber wenn ich dann den Bereich " case R.id.btnStartAZ: " debugge sind die alten Werte wieder drin, als wären Sie nicht gelöscht... Ich hatte auch versucht die Werte bereits in der btnBackFunction() funktion direkt zu löschen, aber da kommt das selbe Problem.

Ich verstehe das nicht ganz mit den SharedPreferences, macht es ein Problem wenn man

SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);
SharedPreferences sprGameField = getSharedPreferences("XX", 0);

öfters aufruft?

Das ist doch einfach nur eine "Datei" die geöffnet wird dort wird was gemacht und gespeichert oder missverstehe ich das?

Danke für eure Hilfe!

VG

— geändert am 19.05.2018, 13:04:24 durch Moderator

Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

19.05.2018, 13:03:38 via Website

Hallo yugox,

Herzlich wilkommen hier im Forum :)


Das ist doch einfach nur eine "Datei" die geöffnet wird dort wird was gemacht und gespeichert oder missverstehe ich das?

Genau das ist inern nur eine XML Datei.

Ich verstehe das nicht ganz mit den SharedPreferences, macht es ein Problem wenn man
SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);
SharedPreferences sprGameField = getSharedPreferences("XX", 0);

öfters aufruft?

Das ist im normalfall kein Problem.

Wenn ich das richtig verstanden habe:
Du löscht alle Preferences um diese auf ButtonClick wieder neu zu speichern.
Das löschen funktioniert im Debug lauf deiner Aussage, aber beim Speichern stehen die "alten Werte" drin?
Wo (Zeile) schaust du, welche werte drin stehen und wie weißt du dass es die alten sind?

Hast du evtl. die Werte beim schreiben nicht aktualisiert?

   eG.putInt("difficulty", difficulty);
            eG.putInt("firstDimension", firstDimension);
            eG.putInt("secondDimension", secondDimension);

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 13:20:45 via Website

Hallo
SharedPreferences löscht man so.

SharedPreference.Editor eG= getApplicationContext().getSharedPreferences("MyPrefs",0).edit();
eG.remove(„xxx“).commit();
eG.remove("XX").commit();

— geändert am 19.05.2018, 13:26:20

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

19.05.2018, 13:45:19 via Website

@Jockel: Dann müsste ich aber jeden Key einzeln löschen.
Mit einem Clear kann ich alle gesammelt löschen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 13:54:12 via Website

Hey Pascal :-)

Vielen Dank für die Begrüßung :)

Also:

if(btnBack) {
    SharedPreferences.Editor eG = sprGameFieldSettings.edit();
    eG.clear();
    eG.commit();
    SharedPreferences.Editor eGF = sprGameField.edit();
    eGF.clear();
    eGF.commit();
}

direkt nach dem IF sehe ich im debugger noch alle Werte und am Ende der IF sind alle Werte gelöscht.
So habe ich überprüft ob dort überhaupt etwas gelöscht wird oder nicht.

Dann habe ich den Debug gestoppt und den Punkt bei:

SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);

gesetzt.

Nun stehen im Debugger aber wieder alle alten Werte drinne, dass heißt Sie wurden scheinbar nicht wirklich gelöscht, obwohl sie bei der if-Abfrage hätte alle gelöscht werden müssen.
Habe ich da ein Denkfehler?

Was ich eben versucht habe und mich etwas wundert ist, dass wenn ich die IF Abfrage weglasse, alle Werte gelöscht bleiben.

Aber wieso... er kommt ja in die IF-Abfrage rein.

— geändert am 19.05.2018, 14:03:25

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 14:03:37 via Website

ob etwas gelöscht wurde siehst du erst nach dem Commit.
Denn da wird es in die Datei gespeichert.
Einzeln löschen machst du ja sowie so den du erstellst für jeden Eintrag eine Variable.
ich mache das so

// Lesen
    SharedPreferences sR = getSharedPreferences("MyPrefs",0);

    int i = sR.getInt("xxx",0);
    String  st = sR.getString("XX","Default");


    // Schreiben
    SharedPreferences.Editor sW = sR.edit();
   // oder 
   SharedPreferences.Editor sW = getSharedPreferences("MyPrefs",0).edit();

    sW.putInt("xxx",10);
    sW.putString("XX","Hallo");
    sW.commit();

    // Löschen
    sW.remove("xxx").commit();
    sW.remove("XX").commit();
    // oder
    sW.remove("xxx");
    sW.remove("XX");
    sW.commit();
    // oder
    sW.clear().commit;

— geändert am 19.05.2018, 14:12:06

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 14:25:51 via Website

Hey Jokel,

danke für die Veranschaulichung :-)

wie das eigentlich in etwa zu funktionieren hat weiß ich, ich benutze es auch in einer anderen Activity und dort funktioniert es.

Es geht nur hier nicht und ich weiß nicht woran es liegt. Was mich halt auch mega stutzig macht ist, dass es ohne den if-Zweig auch gelöscht bleibt... obwohl er auch zu 100% in den if-zweig reingeht.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 14:32:17 via Website

Dann habe ich den Debug gestoppt und den Punkt bei:
SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);

Erstens stoppt man nicht den Debugger sondern lässt ihn bis zu der stelle die man braucht weiter laufen.
außerdem hast du gar kein SheredPreferences Objekt.
das erstellt man so
SharedPreferences.Editor sW = getSharedPreferences("MyPrefs",0).edit(); wobei "MyPrefs" ein frei wählbarer Name ist, und die 0 gibt die Zugriffsrechte an.

Ohne ein Objekt geht es nicht.
Lehsen und Schreiben sind verschiedene Objkte wie du in meinen vorrigen Code sehen kannst.

Teste mal nach dem lösch Commit mit dem Dateiexplorer im Emulator ob die werte in der Datei gelöscht wurden.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 15:07:46 via Website

Ok habe es mir noch mal angesehen du erstellst verschiedene Objekte.
Somit auch mehrere Dateien.
Habe das auf die schnelle etwas falsch Interpretiert.

Wie arbeitest du nach der If weiter? Denn die Variablen eG u. eGF sind nur im If Blog lokal verfügbar.

Kann es sein das

if(sprGameFieldSettings.contains("breakGame")) {
redirectMainActivity();
return;
}

deine mainActivity startet und dort deine Daten wieder neu geschrieben werden?

Ich erstelle mir meistens zwei Globale Variablen zum Lesen und Schreiben im Klassen Rumpf.
Brauch dann nicht immer wieder neu erstellen und gehe nicht gefar auf eine falsche Variable mit gleichen Namen zuzugreifen.
Aber das nur mal als Tipp.

— geändert am 19.05.2018, 15:17:03

Hilfreich?
yugoxPascal P.
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 15:23:46 via Website

Nee, wenn die Anwendung z.B. beendet wird, dann werden die Einstellungen gespeichert. Wenn man die Anwendung nun wieder startet, dann gelangt man in

if(sprGameFieldSettings.contains("breakGame")) {
redirectMainActivity();
return;
}

Das funktioniert auch alles super.

Wenn man aber auf den Zurück-Button geht, dann wird ja alles in dem IF-Zweig gelöscht, dementsprechend geht er auch gar nicht mehr in:

if(sprGameFieldSettings.contains("breakGame")) {
redirectMainActivity();
return;
}

rein, weil es logischerweise gelöscht wurde (Habs gedebuggt).

Wie arbeitest du nach der If weiter?

Wenn man den Zurück-Button gedrückt hat und der ganze Ablauf fertig ist, dann kann man sogesehen ein neues Spiel erzeugen. Man hat halt ein Button auf den man drückt um ein neues Spiel zu erzeugen -> Switch case:

@Override

public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartAZ:
SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);
SharedPreferences.Editor eG = sprGameFieldSettings.edit();
eG.putInt("difficulty", difficulty);
eG.putInt("firstDimension", firstDimension);
eG.putInt("secondDimension", secondDimension);
eG.apply();

        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
        break;

    default:
        break;
}

}

Danach gelangt man wieder auf die andere Intent, von der man gekommen ist.
Ich gelange auch dahin, nur halt mit den vorherigen Einstellungen statt mit neuen.

Und wegen dem Button-Click musste ich den Debug stoppen, damit ich den click auf ausführen kann.

Dateiexplorer im Emulator

Wo genau befindet sich der Explorer? Ich finde ihn nicht.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 15:49:00 via Website

Der Dateiexplorer ist auf der rechten Seite bei AS, wenn er gestratet ist.
image

Path /datei/datei/projektname/shared_prefs/xxx.xml

image

— geändert am 19.05.2018, 15:57:46

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 16:42:10 via Website

Könne auch daran liegen das du auf eine altes Preferences Objekt zu greifst was noch nicht gelöscht wurde. Wie gesagt ist es sinnvoller nicht immer ein neues Objekt zu erstellen.
Wie du in meinen Beispiel siehst wird richtig gelöscht.

Wenn "case R.id.btnStartAZ: " der Start eines neuen Spiels ist wie so löschst du nicht dort deine Einstellungenen? Du schreibst ja dort auch wieder neue Werte in die Preferences.

— geändert am 19.05.2018, 16:57:47

Hilfreich?
yugox
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 17:10:44 via Website

Genau, die Einstellungen werden ja beim IF-Zweig gelöscht -> Ich habe nun mir auch die XML Datei angeschaut, wenn ich im IF-Zweig debugge und dort wird auch alles gelöscht.

Aber wenn ich den debug Punkt beim case btnStartAZ setze, sind die Werte da.
Ich versuch es mal mit einem einzigen Objekt hinzubekommen, kann vielleicht daran liegen, dass ein altes Objekt genommen wird.

Aber ich frage mich, wieso bleibt es denn gelöscht, wenn die IF-Abfrage nicht statt findet sondern einfach direkt gelöscht wird.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 17:28:44 via Website

Zeige mal deinen Code im Zusammenhang.

In welcher Methode hast du den Code von "Intent NR 2" also deine If -Affrage und Löschung ?
Ist Löschung und Clicklistner in der gleichen Activity?

Wie gesagt fehlt mir etwas der Zummenhang deiner Methoden.

— geändert am 19.05.2018, 17:42:41

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 17:43:04 via Website

Der obere Code wird immer zuerst aufgerufen und bei diesem wird das Spiel generiert. Hier werden die Preferences aufgerufen.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SharedPreferences sprGameFieldSettings = getSharedPreferences("xxx", 0);

    this.firstDimension = sprGameFieldSettings.getInt("firstDimension", 4);
    this.secondDimension = sprGameFieldSettings.getInt("secondDimension", 4);
    this.difficulty = sprGameFieldSettings.getInt("difficulty", 0);
Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 17:47:43 via Website

In welcher Methode hast du den Code von "Intent NR 2" also deine If -Affrage und Löschung ?
Ist Löschung und Clicklistner in der gleichen Activity?

Also Intent NR 1

    @Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btnRefresh:
            startNewGame();
            break;
        case R.id.btnBack:
            btnBackFunction();
            break;
        default:
            startNewGame();
            break;
    }
}

}

    private void btnBackFunction() {
        Intent intent = new Intent(this, MenuActivity.class);
        intent.putExtra("btnBack", true);
        startActivity(intent);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        finish();
}

DANACH wird ja Intent NR 2 aufgerufen, was Du oben siehst.
Der 1. Clicklistener ist in der 1. Intent und die Löschung in der 2. Intent und für das starten des neuen Spiels mit neuen Werten auf in der 2. Intent.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 17:49:51 via Website

Ja Ok und wie geht es weiter?
Wo ist deine Löschmethode ?
Das alleine bringt uns nicht weiter.

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 17:58:18 via Website

Hier wird doch alles gelöscht ?

this.sprGameFieldSettings = getSharedPreferences("MasterOfLettersGameFieldSettings", 0);

    Intent myIntent = getIntent();
    Boolean btnBack = myIntent.getBooleanExtra("btnBack", false);

 if(btnBack) {
    SharedPreferences.Editor eG = sprGameFieldSettings.edit();
    eG.clear();
    eG.commit();
    SharedPreferences.Editor eGF = sprGameField.edit();
    eGF.clear();
    eGF.commit();
}

— geändert am 19.05.2018, 17:58:55

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 18:02:19 via Website

ja aber was wird nach dem löschen gemacht?

Warum löschst du nicht einfach in deiner NewGame Methode?
Und wichtig, wenn du einen Intent ausführst und somit eine neue Activity startest wird auch die oncread wieder ausgeführt vielleicht hast du dort noch eine Speicher Funktion enthalten die die Werte wider setzt.

— geändert am 19.05.2018, 18:10:32

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 18:06:39 via Website

Eigentlich nichts mehr, er läuft halt bis zum ende durch und es wird gewartet bis ein click event ausgelöst wird.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 18:12:49 via Website

wo genau in welcher Methode bei welchen Button Click löschst du?

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 18:26:47 via Website

Könnte es sein das du es mit den Default Werten verwechselst?

this.firstDimension = sprGameFieldSettings.getInt("firstDimension", 4);

Hier wird wenn keine Preference gefunden wird der Default Wert 4 in die Variable „this.firstDimension“ gespeichert. Also auch wenn du gelöscht hast.

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 18:37:37 via Website

Oh man ist das kompliziert... :) Nee ich verwechsel es nicht. Es ist eine Einreihung von Buttons und die Dimensionale Größe ändert sich auch entsprechend was ich vorher ausgewählt habe, also firstDimension,etc. wird schon richtig mit angegeben, die Datei wird scheinbar mit den neuen Werten übergeben. Aber die anderen Werte sind alle noch vorhanden.

ich habe es nun hinbekommen...

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 18:39:36 via Website

      this.sprGameFieldSettings = getSharedPreferences("xxx", 0);
    this.sprGameFields = getSharedPreferences("xx", 0);
    this.sprGameFieldSettingsEditor = this.sprGameFieldSettings.edit();
    this.sprGameFieldsEditor = this.sprGameFields.edit();

        Intent myIntent = getIntent();
    Boolean btnBack = myIntent.getBooleanExtra("btnBack", false);
    if(this.sprGameFieldSettings.contains("breakGame") && !btnBack) {
        redirectMainActivity();
    }

case R.id.btnStartAZ:

            Intent myIntent = getIntent();
            Boolean btnBack = myIntent.getBooleanExtra("btnBack", false);
            if(btnBack) {
                this.sprGameFieldSettingsEditor.clear().commit();
                this.sprGameFieldsEditor.clear().commit();
            }

            this.sprGameFieldSettingsEditor.putInt("difficulty", difficulty);
            this.sprGameFieldSettingsEditor.putInt("firstDimension", firstDimension);
            this.sprGameFieldSettingsEditor.putInt("secondDimension", secondDimension);
            this.sprGameFieldSettingsEditor.commit();

            Intent intent = new Intent(this, MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
            finish();
            break;

auch wenn ich immer noch nicht ganz verstehe wieso es nicht wie vorher ging..

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

19.05.2018, 19:30:31 via Website

@Jokel

vielen Dank für deine Unterstützung und die Tipps! :-)

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.05.2018, 19:52:02 via Website

Eine Frage zum Schluss wo findendet den jetzt die Variablen Definition statt? Im Klassen Rumpf als globale Variable.

Hilfreich?
Kommentieren
yugox
  • Forum-Beiträge: 27

22.05.2018, 09:29:23 via Website

Jap, ich habe das mal alles etwas umgemoddelt und Sie als globale Variablen zur Verfügung gestellt.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

22.05.2018, 10:56:15 via Website

Ok dachte ich mir, ist auch einfacher zu Händeln.

Hilfreich?
Kommentieren