2017-01-10 4 views
-1

Ich habe serialisiert erfolgreich mein benutzerdefiniertes Objekt, aber wenn ich deserialisieren es dies geschieht:deserialisiert Objektfelder sind null

-Custom Objekt NOT NULL ist

-Alle Felder NULL sind

Ich weiß, dass ich habe mein benutzerdefiniertes Objekt erfolgreich serialisiert, weil ich die Serialisierungsdatei gelesen habe und sie gut aussieht.

Hier ist mein Code:

public class Preferences implements Serializable { 

private static Preferences instance; 
public static final long serialVersionUID = 3358037972944864859L; 
public String accessToken; 

protected Object readResolve() { 
    return getInstance(); 
} 

private Preferences() { 

} 

private synchronized static void synchronize() { 
    if(instance == null) { 
     instance = new Preferences(); 
    } 
} 

public static Preferences getInstance() { 
    if(instance == null) { 
     Preferences.synchronize(); 
    } 

    return instance; 
} 

public void save(File file) { 
    try { 
     FileOutputStream fos = new FileOutputStream(file); 
     ObjectOutputStream out = new ObjectOutputStream(fos); 

     Preferences tempInstance = Preferences.getInstance(); 

     out.writeObject(tempInstance); 
     out.close(); 
     fos.close(); 
    }catch(IOException e) { 
     e.printStackTrace(); 
    } 
} 

public void load(File file) { 
    try { 
     FileInputStream fis = new FileInputStream(file); 
     ObjectInputStream in = new ObjectInputStream(fis); 

     if(file.length() > 0) { 
      Preferences tempInstance = (Preferences) in.readObject(); 

      Log.e("", String.valueOf(tempInstance == null)); //prints FALSE 
      Log.e("", String.valueOf(tempInstance.accessToken == null)); //prints TRUE 
     } 

     in.close(); 
     fis.close(); 
    }catch(IOException | ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 
} 
} 

Hier ist mein Testcode:

public class CustomActivity extends AppCompatActivity { 

private File dir = new File(Environment.getExternalStorageDirectory(), ".app"); 
private File backup = new File(dir, "backup.ser"); 

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    Log.e("APPLICATION", "START"); 

    super.onCreate(savedInstanceState); 

    if(this instanceof ActivityLogin) { 
     if(!dir.exists()) { 
      dir.mkdirs(); 
     } 

     Preferences.getInstance().load(backup); 
    } 
} 

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

    try { 
     backup.createNewFile(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    Preferences.getInstance().save(backup); 

    Log.e("APPLICATION", "STOP"); 
} 

}

Irgendwelche Gedanken auf, was ein Problem sein könnte?

+0

Sie tun nichts mit dem gelesenen Objekt. Ihre Lademethode sollte statisch sein und die deserialisierte Instanz zurückgeben. 'instance' und' this' sind zwei verschiedene, nicht verwandte Objekte. –

+0

Ich mache etwas mit Instanz-Objekt, nachdem load() fertig ist, aber in der load() - Instanz ist nicht null, während alle ihre Felder null sind. Bitte sehen Sie meine Bearbeitung. @ JBNizet – jelic98

+0

Geben Sie ein vollständiges minimales Beispiel ein, das den Fehler reproduziert. Wir haben keine Ahnung, was Sie serialisieren und deserialisieren. –

Antwort

3

Sie haben diese Methode in Ihrer Klasse:

protected Object readResolve() { 
    return getInstance(); 
} 

Dies teilt dem Serialisierungsmechanismus: wenn Sie eine Preferences Instanz deserialisieren, wird es durch einen von getInstance() zurück ersetzen. Wenn Sie also load() aufrufen und die Instanz Ihrer Einstellungen einen null accessToken hat, dann haben die deserialisierten Einstellungen auch einen null accessToken, da sie das gleiche Objekt sind.

System.out.println(tempInstance == this); 

auf Ihre Logging-Anweisungen hinzufügen (oder was auch immer Sie in Android verwenden, um log), und Sie werden sehen.

+0

Ok, danke. Sollte ich diese Methode entfernen? – jelic98

+1

Ja. Aber ich würde auch aufhören, das schreckliche Singleton Anti-Muster zu verwenden. Machen Sie die Lade-Methode einfach statisch, lassen Sie die deserialisierten Einstellungen zurück und speichern Sie sie in einer Variablen. –

+0

Ich habe die Lade-Methode statisch gemacht und das Präferenzen-Objekt zurückgegeben. Was passiert, wenn ich setInstance() erstelle, das Instanz-Feld setzt und load() als Parameter übergibt? – jelic98