IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Serializable et mise à jour


Sujet :

Android

  1. #1
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut Serializable et mise à jour
    Bonjour,

    J'utilise ceci pour sauvegarder un objet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public void saveToStream(Context context) {
                try {
                    FileOutputStream stream = context.openFileOutput(FILENAME, 0);
                    ObjectOutputStream out = new ObjectOutputStream(stream);
                    out.writeObject(this);
                    out.close();
                    stream.close();
                } catch (Exception e) {
                    Log.d("DBG", "Erreur saveToSTream: " + e.getMessage());
                }
            }
    je peux facilement le relire, mais cet objet complexe qui contient des listes d'objets, des HashMap... est incorrectement lu (des champs sont null) quand je relis le fichier après une mise à jour de l'APK, même quand les modifications ne concernent pas l'objet sérialisé.

    et ça c'est très embêtant !

    est-ce un phénomène connu, un pb dans mon code, existe-il une autre méthode pour sauvegarder facilement des objets dans un format persistant malgré l'update de l'APK ?

    les objets sont de ce type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    package truc;
    public class LesChoses {
      public static class Chose1 implements Serializable {
        int id;
        String name;
      }
      public static class Chose2 implements Serializable {
        int id;
        String name;
        Chose1 chose1;
      }
      public static class Choses implements Serializable {
        ArrayList<Chose1> choses1 = new ArrayList<Chose1>();
        HashMap<Integer, Chose2> choses2 = new HashMap<Integer, Chose2>();
        public void saveToStream(...);
      }
     
      private static Choses mChoses;
      public static Choses getChose() { 
        ...// singleton
      }
    }
    NB: le volume de données est suffisamment réduit pour que je ne veuille pas passer par une BDD, je veux juste que ce soit persistant.

    Merci
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  2. #2
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Tu peux t'intéresser au Parcelable, qui est similaire au Serializable en plus complet pour Android.

    Site créant automatiquement : http://devk.it/proj/parcelabler/

    Je n'ai pas eu de problèmes de champ null après désérialisation. Par contre, pour te dire si ça va ou pas, il faudrait le code correspondant (à la limite en omettant les transient, qui sont null normalement).
    Je t'avoue que je n'ai pas testé une serial/deserial avec une MaJ appli entre les deux par contre.
    C'est Android, PAS Androïd, ou Androïde didiou !
    Le premier est un OS, le second est la mauvaise orthographe du troisième, un mot français désignant un robot à forme humaine.

    Membre du comité contre la phrase "ça marche PAS" en titre et/ou explication de problème.

    N'oubliez pas de consulter les FAQ Android et les cours et tutoriels Android

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    merci, je crois que j'ai trouvé où était le problème bien que je ne comprenne pas pourquoi ça fonctionnait sans rebuild.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      public static class parent {
        public String name;
      }
      public static class enfant1 extends parent implements Serializable {
        public int count;
      }
      public static class enfant2 extends parent implements Serializable {
        public int size;
      }
    j'ai ajouté Serialize sur le parent...ça me paraissait redondant puisque je n'instancie jamais parent mais uniquement des descendants qui sont tous Serializable...je m'étais poser la question en déclarant mes classes mais n'avais pas trouvé d'indication à ce sujet alors j'avais supposé que l'interface s'appliquait aux membres hérités.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    En fait non...

    L'interface "Serializable" est vide, et est juste utilisée comme flag (à l'époque ou les annotations n'existaient pas encore) pour le code de serialization.

    Et si une classe peut être sauvée, elle doit implémenter Serializable.
    Si l'effet était hérité, imagine que quelqu'un crée une classe fille pas serializable (pour X raisons)... ou même serializable, mais sans modifier le serialize-id ....

    D'ailleurs, à propose d'id, ils sont ou les serialized-id de tes classes ?
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    alors pour le coup je ne parlais pas d'hériter du serializable mais de sérialiser les membres hérités (dans mon exemple parent.name n'est pas sérialisé si j'ai tout compris)

    quand au serialized-id j'en découvre l’existence je vais de ce pas les ajouter.

    je ne suis pas tout jeune en programmation mais j'ai fait l'impasse sur Java, le langage n'est pas bien compliqué à apprendre, il me reste le plus gros du travail: me familiariser avec le framework.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par nicroman Voir le message
    En fait non...

    L'interface "Serializable" est vide, et est juste utilisée comme flag (à l'époque ou les annotations n'existaient pas encore) pour le code de serialization.

    Et si une classe peut être sauvée, elle doit implémenter Serializable.
    Si l'effet était hérité, imagine que quelqu'un crée une classe fille pas serializable (pour X raisons)... ou même serializable, mais sans modifier le serialize-id ....

    D'ailleurs, à propose d'id, ils sont ou les serialized-id de tes classes ?
    alors après quelques recherches je suis dans l’incertitude face à ton message.

    sur cette page, il est dit clairement que "Toutes les classes dérivées d’une class sérialisable sont aussi sérialisables", d'autre part, serialVersionUID étant static, et si je ne m'abuse il n'est pas hérité et la classe enfant aura un serial calculé automatiquement comme toute classe pour laquelle on n'a pas défini de serial.

    En fait si j'ai bien compris, le seul intérêt de définir soit même le serial id c'est de pouvoir ajouter des méthodes à la classe sans changer son serial id (puisque l'id calculé tient compte des méthodes); par contre il faut modifier son id quand on modifie ses membres...je trouve cela finalement plus une contrainte qu'un atout.

    J'aurais tendance dans ce contexte à déclarer des structures sérializables et déporter les méthodes dans une autre classe...quelque chose comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    public class ToolBox {
     
      public static class Data implements Serializable {
        String info;
      }
     
      private Data mData = new Data();
     
      public String getInfo() {
        reutrn mData.info;
      }
     
      public void setInfo(String info) {
        mData.info = info;
      }
     
      public void save() {
        ...writeObject(mData);
      }
     
      public void load() {
        ...mData = (Data)readObject();
      }
    }
    dès lors le serial id de ToolBox.Data ne changera que lorsque ses membres changeront.

    Qu'en pensez-vous ?
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Alors pour être précis... tout objet héritant de Serializable (y compris indirectement) est considéré pour le code de serialization comme "serializable". L’inconvénient ici, c'est qu'il devient facile de "casser" le soft, par simple héritage et de manière totalement "invisible" pour le code de serialization.

    Par exemple:
    class A implement Serializable
    ArrayList<B> allBs;

    class B implements Serializable
    ....

    class C extends B
    NonSerializableType d;

    il suffit alors de rajouter des objets de type "C" dans la liste de A pour que la serialization de A produise une erreur. Et le code de A n'a aucun moyen de le savoir

    Enfin bref, tout ça pour dire que la serialization par defaut de Java est une horreur et que j'ai toujours tout fait pour l'éviter


    Le problème de l'id n'est pas tant sur quand le changer ou non... Le problème est que si il n'est pas explicite, une JVM peut utiliser un ID différent d'une autre JVM, sans que les classes n'aient été modifiées d'un iota.

    Et pour l'exemple choisi, ce sont des ToolBox qu'on veut sauver, et pas des ToolBox.Data .... donc le problème est juste déporté. Même pas sur que writeReplace puisse aider dans ce cas précis !
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment empêcher la mise à jour d'un contrôle à l'écran ?
    Par JojoLaFripouille dans le forum Composants VCL
    Réponses: 4
    Dernier message: 19/09/2003, 12h52
  2. [mise à jour]Comment procéder sans tout péter...
    Par FFF dans le forum Installation
    Réponses: 3
    Dernier message: 10/09/2003, 08h11
  3. Mise à jour de la version de MySQL
    Par jobstar dans le forum Administration
    Réponses: 8
    Dernier message: 18/08/2003, 10h45
  4. mise à jour de champs time (interbase)
    Par pram dans le forum XMLRAD
    Réponses: 6
    Dernier message: 04/03/2003, 10h25
  5. Réponses: 2
    Dernier message: 12/02/2003, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo