2017-12-27 19 views
1

Ich habe eine Singleton-Klasse namens DataManager. Ich aktualisiere einige Daten in DataManager, wenn ich onStop() in einer Klasse (activity) genannt userProfile aufrufen. Es nimmt die Werte aus einigen Texteingabefeldern und aktualisiert das Objekt User in DataManger. Ich navigiere durch meine App mit einer BottomNavigationView - also wenn ich das Home-Icon aus der userProfile Ansicht drücke, sollte ich die userProfileonStop() anrufen und die Werte aktualisieren. Das funktioniert richtig. Ich bin durch den Code gegangen und die Werte in meiner singleton Klasse werden korrekt aktualisiert. Das Problem tritt auf, wenn ich versuche, die Werte von der Homepage zu lesen. Die Werte wurden noch nicht aktualisiert. ABER wenn ich die Ansicht erneut öffne oder eine andere Ansicht öffne, sind die Werte in DataManager die korrekten aktualisierten Werte. Was denkst du, ist das Problem?Android - Singleton Klasse nur bei Aktualisierung aktualisiert

Ich bin nicht sicher, ob seine relevanten, aber home und userProfile beide erben von einer Basisklasse, die die onCreate()-Methode von beiden untergeordneten Klassen enthält.

Singleton Klasse DataManager genannt:

public class DataManager { 

private static DataManager only_instance = null; 

public List<Facility> facilities; 
public List<Procedure> procedures; 
public static User theUser; 

public DataManager(){ 
    only_instance.theUser = new User(); 
} 

public static DataManager getInstance(){ 
    if(only_instance == null){ 
     only_instance = new DataManager(); 
    } 

    return only_instance; 
} 
} 

Die OnStop() -Methode von Userprofile

@Override 
    protected void onStop(){ 
super.onStop();  

DataManager dm = DataManager.getInstance(); 

dm.theUser.<SET LOTS OF VALUES> 
} 
+0

Gehen Sie von userProfile zu homePage zurück? –

+0

Es ist im Allgemeinen eine gute Übung, einen privaten Standardkonstruktor zu schreiben, damit Sie nicht versehentlich eine neue Instanz ohne Bedeutung erstellen. Auch @Archit wies darauf hin, dass Sie eine neue Objekterzeugung innerhalb eines Synchronisierungsblocks einschließen sollten. Oder noch besser: Synchronisieren Sie die gesamte Methode. – Abbas

+0

@TentenPonce Ich glaube nicht, dass ich zurück gehe - es ist nur zu verschiedenen Aktivitäten, die ich hin- und herwechseln mit einem Bottom Navigation Manager –

Antwort

0

Das Problem liegt eigentlich in der Android-Lebenszyklus. Aus irgendeinem Grund wurde die onCreate() - Funktion in der Homepage-Klasse aufgerufen, bevor die onStop() - Funktion in der userProfile-Klasse aufgerufen wurde. Ich bin ehrlich gesagt nicht genau warum - aber onStop() zu onPause() zu ändern löste mein Problem.

0

Das Problem, das Sie faul ist Ihre Singleton geladen. Es funktioniert, wenn Sie Ihre App aktualisieren, weil Sie onStop aufrufen und Ihr Singleton initialisieren. Aber vorher haben Sie keine Singleton-Instanz geladen (es ist null). Wenn Sie die faule Initialisierung entfernen, funktioniert es. Ändern

if(only_instance == null){ //This is called "lazy loading" 
    only_instance = new DataManager(); 
} 

zu

private static final DataManager only_instance = new DataManager(); //you can optionally add final here if you're removing lazy loading. In fact, it's probably best practice to do so. 

public List<Facility> facilities; 
public List<Procedure> procedures; 
public static User theUser; 

public DataManager(){ 
    only_instance.theUser = new User(); 
} 

public static DataManager getInstance(){ 
    return only_instance; 
} 

Auf diese Weise sind Sie Singleton Instanz so schnell geladen werden wie die Klasse geladen wird. Wenn Sie die Instanz Ihres Singleton nicht sofort benötigen, ist das Lazy Loading angenehm, aber in Ihrem Fall brauchen Sie es sofort.

+0

Schätzen Sie die Hilfe - aber leider hat das das Problem für mich nicht gelöst ... –

0

Ich gehe davon aus, dass es wegen Synchronisierung Problem sein kann.

ASingleton result = instance; 
     if (result == null) { 
      synchronized (mutex) { 
       result = instance; 
       if (result == null) 
        instance = result = new ASingleton(); 
      } 
     } 
     return result; 

und Wenn Sie nicht denBEDIENEREINGABENdes ohne DataManager- Instanz verwenden, dann sollte es nicht statisch sein: so sollten wir die Threadsicherheit Singleton mit Hilfe von synchronisierten() Schlüsselwörter wie unten verwenden.

für mehr über die Threadsicherheit Singleton Sie diesen Link für weitere Informationen verweisen

https://www.journaldev.com/171/thread-safety-in-java-singleton-classes-with-example-code

Verwandte Themen