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 :

re-open an already-closed object : SQLiteDatabase


Sujet :

Android

  1. #1
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut re-open an already-closed object : SQLiteDatabase
    Bonjour,

    Je vais essayer d'exprimer mon besoin dans des termes claire... (C'est pas gagné )

    Je développe une application Android pour m'entrainer sur les bases de SQLite.
    J'ai fait une classe "BDD" de ma classe "metier" (par exemple ma classe métier normal Medicament, je lui est faite une classe MedicamentBDD qui contient les curseurs que j'ai besoin pour manipuler mon objet dans SQL).

    Lorsque j'appelle ces classe dans mon Activity, tout ce passe normalement.

    C'est alors que le drame arrive:

    J'ai besoin d'ajouter un bouton avec une action onclick (jusque là, tout va bien) mais je n'arrive plus à utiliser les classes MedicamentBDD !

    Je joint le code pour avoir une idée du souci...
    Un élément de ma classe BDD:
    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
    26
    27
    28
    29
    	public Medicament getMedicamentWithId(int ID){
    		//Récupère dans un Cursor les valeur correspondant à un medicament contenu dans la BDD	
    		Cursor cursor = bdd.query(GestionnaireBaseSQL.TABLE_NAMEmedicament,
                    new String[] { COL_ID,
    							COL_NAME,
    							COL_MOLECULE},
    							COL_ID + "=?",
                    new String[] { String.valueOf(ID) }, null, null, null);
    		return cursorToMedicament(cursor);
    	}
     
    	//Cette méthode permet de convertir un cursor en un medicament
    	private Medicament cursorToMedicament(Cursor c){ 
    		//si aucun élément n'a été retourné dans la requête, on renvoie null
    		//if (c.getCount() == 0)
    		//	return null;
     
    		//Sinon on se place sur le premier élément
    		c.moveToFirst();
    		//On créé un medicament
     
    		Medicament medicament = convertCursorToObject(c);
     
    		//On ferme le cursor
    		c.close();
     
    		//On retourne le medicament
    		return medicament;
    	}
    Le code de mon Activity:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    MedicamentBDD medicamentBDD = new MedicamentBDD(this);
    medicamentBDD.open();
    Medicament medoc = medicamentBDD.getMedicamentWithId(0);  //FONCTIONNE CORRECTEMENT 
     
    		Button bt_name = (Button) findViewById(R.id.bt_name);
    		bt_name.setOnClickListener(new View.OnClickListener() {
    	        public void onClick(View arg0) {
     
     
    	        	Medicament medoc = medicamentBDD.getMedicamentWithId(0); //NE FONCTIONNE PAS ! 
    	        }
    		});
    Le LogCat:
    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
    26
    27
    28
    29
    30
     
    02-26 09:12:56.374: W/EGL_emulation(11649): eglSurfaceAttrib not implemented
    02-26 09:12:56.404: D/OpenGLRenderer(11649): Enabling debug mode 0
    02-26 09:13:02.264: W/FileUtils(11649): Failed to chmod(/data/data/com.example.pharmacie/databases/Pharmacie): libcore.io.ErrnoException: chmod failed: EPERM (Operation not permitted)
    02-26 09:13:02.284: W/FileUtils(11649): Failed to chmod(/data/data/com.example.pharmacie/databases/Pharmacie): libcore.io.ErrnoException: chmod failed: EPERM (Operation not permitted)
    02-26 09:13:02.304: W/FileUtils(11649): Failed to chmod(/data/data/com.example.pharmacie/databases/Pharmacie): libcore.io.ErrnoException: chmod failed: EPERM (Operation not permitted)
    02-26 09:13:02.494: W/EGL_emulation(11649): eglSurfaceAttrib not implemented
    02-26 09:13:07.174: D/AndroidRuntime(11649): Shutting down VM
    02-26 09:13:07.174: W/dalvikvm(11649): threadid=1: thread exiting with uncaught exception (group=0xada54ba8)
    02-26 09:13:07.204: E/AndroidRuntime(11649): FATAL EXCEPTION: main
    02-26 09:13:07.204: E/AndroidRuntime(11649): Process: com.example.pharmacie, PID: 11649
    02-26 09:13:07.204: E/AndroidRuntime(11649): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.example.pharmacie/databases/Pharmacie
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1156)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at com.example.pharmacie.dao.MedicamentBDD.getMedicamentWithId(MedicamentBDD.java:117)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at com.example.pharmacie.ihm.SupprimerActivity$1.onClick(SupprimerActivity.java:175)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.view.View.performClick(View.java:4438)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.view.View$PerformClick.run(View.java:18422)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.os.Handler.handleCallback(Handler.java:733)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.os.Handler.dispatchMessage(Handler.java:95)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.os.Looper.loop(Looper.java:136)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at android.app.ActivityThread.main(ActivityThread.java:5017)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at java.lang.reflect.Method.invokeNative(Native Method)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at java.lang.reflect.Method.invoke(Method.java:515)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
    02-26 09:13:07.204: E/AndroidRuntime(11649): 	at dalvik.system.NativeStart.main(Native Method)
    02-26 09:13:09.174: I/Process(11649): Sending signal. PID: 11649 SIG: 9


    PS: Je développe sous Windows avec Eclipse et j'ai comme AVDM une Nexus 10 4.4.2

  2. #2
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Par défaut
    Bonjour,

    Tout d'abord je pense que ta variable medicamentBDD doit être en final.

    De plus, si tu supprimes le 1er appel (avant le onClick), est ce que le deuxième fonctionne (dans le onClick)?

    Si oui, essayes de fermer le curseur dans ta première fonction :
    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
    26
    27
    28
    29
    30
     
    public Medicament getMedicamentWithId(int ID){
    		//Récupère dans un Cursor les valeur correspondant à un medicament contenu dans la BDD	
    		Cursor cursor = bdd.query(GestionnaireBaseSQL.TABLE_NAMEmedicament,
                    new String[] { COL_ID,
    							COL_NAME,
    							COL_MOLECULE},
    							COL_ID + "=?",
                    new String[] { String.valueOf(ID) }, null, null, null);
    		Medicament medicament = cursorToMedicament(cursor);
     
    		if (cursor != null && !cursor.isClose ())
    			cursor.close ();
     
    		return medicament;
    	}
     
    	//Cette méthode permet de convertir un cursor en un medicament
    	private Medicament cursorToMedicament(Cursor c){ 
    		//si aucun élément n'a été retourné dans la requête, on renvoie null
    		//if (c.getCount() == 0)
    		//	return null;
     
    		//Sinon on se place sur le premier élément
    		c.moveToFirst();
    		//On créé un medicament
     
    		//On retourne le medicament
    		return convertCursorToObject(c);
    	}
    Pour finir, assure toi que ta fonction convertCursorToObject ne ferme pas le curseur.

  3. #3
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut
    Erreur de copier coller pour le final, il est bien présent.

    Le fait d'enlever le première appel ne règle pas le souci... D'ailleurs quand on regarde le log, on voit que c'est la ligne 117 qui plante et c'est celle qui fait le cursor.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Cursor cursor = bdd.query(GestionnaireBaseSQL.TABLE_NAMEmedicament,
                    new String[] { COL_ID,
    							COL_NAME,
    							COL_MOLECULE},
    							COL_ID + "=?",
                    new String[] { String.valueOf(ID) }, null, null, null);

  4. #4
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Par défaut
    Dans ce cas, ton problème vient de ta variable bdd que tu doit fermer quelques part dans ton code...
    Fais quelques recherche sur google et tu verras que l'erreur est fréquente. Il suffit de faire attention d'utiliser la bonne variable et de la supprimer quand il faut.

  5. #5
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut
    Pour pas prendre de risque j'ai commenté tout mon code et le problème persiste ...

    Avant le onclick, sa fonctionne parfaitement, une fois dans le onclick, impossible a faire fonctionner !
    Je ne comprend vraiment pas...

    De plus j'ai fait des recherches sur Google avant de demander de l'aide sur kle forum avec les mots clés "Failed to chmod", "chmod failed: EPERM (Operation not permitted)" ou même "eglSurfaceAttrib not implemented" mais je ne trouve rien ...

  6. #6
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Par défaut
    Citation Envoyé par kratoce Voir le message
    Pour pas prendre de risque j'ai commenté tout mon code et le problème persiste ...

    Avant le onclick, sa fonctionne parfaitement, une fois dans le onclick, impossible a faire fonctionner !
    Je ne comprend vraiment pas...
    et si tu supprimes le 1er appel le second ne fonctionne toujours pas?

    Citation Envoyé par kratoce Voir le message
    De plus j'ai fait des recherches sur Google avant de demander de l'aide sur kle forum avec les mots clés "Failed to chmod", "chmod failed: EPERM (Operation not permitted)" ou même "eglSurfaceAttrib not implemented" mais je ne trouve rien ...
    Et avec le nom de ton erreur : re-open an already-closed object : SQLiteDatabase

  7. #7
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut
    Citation Envoyé par David55 Voir le message
    et si tu supprimes le 1er appel le second ne fonctionne toujours pas?
    Toujours pas...

    Je vais chercher du coté de google alors. Par contre, pourquoi ces mots là? Ils sont dans le log?

  8. #8
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Par défaut
    Oui ils sont dans tes logs (ligne 12)

  9. #9
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut
    Je reviens vers vous, je ne trouve pas mon bonheur. Google c'est vraiment pas au point pour faire des recherches

    Plus sérieusement, je pense que ce message n'est qu'une conséquence du problème. Je me demande si le souci ne viens pas plutôt des première lignes: "Failed to chmod(/data/data/com.example.pharmacie/databases/Pharmacie): libcore.io.ErrnoException: chmod failed: EPERM (Operation not permitted)". Je sais pas si je comprend bien, mais en gros (comme c'est un noyau linux) il n'a pas les permissions d'ouvrir la bdd depuis le button onclick. Je sais c'est tiré par les cheveux, mais je suis un peu perdu

  10. #10
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Par défaut
    Si tu y arrives une première fois je ne vois pas pourquoi ca ne fonctionnerais pas...

    Ceci fonctionne bien?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    MedicamentBDD medicamentBDD = new MedicamentBDD(this);
    medicamentBDD.open();
    Medicament medoc = medicamentBDD.getMedicamentWithId(0);
    Essayes ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    		Button bt_name = (Button) findViewById(R.id.bt_name);
    		bt_name.setOnClickListener(new View.OnClickListener() {
    	        public void onClick(View arg0) {
     MedicamentBDD medicamentBDD = new MedicamentBDD(this);
    medicamentBDD.open();
    Medicament medoc = medicamentBDD.getMedicamentWithId(0);
    	        }
    		});
    Si c'est ok, essayes ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    final MedicamentBDD medicamentBDD = new MedicamentBDD(this);
    medicamentBDD.open();
    		Button bt_name = (Button) findViewById(R.id.bt_name);
    		bt_name.setOnClickListener(new View.OnClickListener() {
    	        public void onClick(View arg0) {
    Medicament medoc = medicamentBDD.getMedicamentWithId(0);
    	        }
    		});
    Si ca ne fonctionne pas essaye la même chose mais en mettant medicamentBDD en variable de classe. Sinon, je te propose de revoir ta gestion de BDD car tu as un soucis.

    Personnellement j'utilise ORMLite.

  11. #11
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut
    Citation Envoyé par David55 Voir le message
    Essayes ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    		Button bt_name = (Button) findViewById(R.id.bt_name);
    		bt_name.setOnClickListener(new View.OnClickListener() {
    	        public void onClick(View arg0) {
     MedicamentBDD medicamentBDD = new MedicamentBDD(this);
    medicamentBDD.open();
    Medicament medoc = medicamentBDD.getMedicamentWithId(0);
    	        }
    		});
    C'est peut-être la que j'ai un souci.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MedicamentBDD medicamentBDD = new MedicamentBDD(this);
    Il ne veux pas prendre le this dans le button. Le même code que je met en dehors du button il l'accepte mais pas la.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The constructor MedicamentBDD(new View.OnClickListener(){}) is undefined

  12. #12
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Par défaut
    Autant pour moi, il ne faut pas mettre this mais le nom de ton activité suivi de this : MyActivity.this

  13. #13
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut
    C'est exactement ce qu'il me manque !

    Un grand merci pour ta patience et ton aide !!!

  14. #14
    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 : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Par défaut
    Et petite explication :
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // this désigne toujours la classe courante.
    // ici, il désignera la classe englobante.
    bt_name.setOnClickListener(new View.OnClickListener() {
        // ici, this désigne la classe anonyme interne créée, implémentant l'interface View.OnClickListener 
        public void onClick(View arg0) {
                // ainsi, ici, this n'est pas une Activity ou un Fragment, mais un View.OnClickListener anonyme
                // Pour désigner la classe englobante, Java utilise l'écriture ClasseEnglobante.this pour ce genre de cas
                // ClasseEnglobante.this dit explicitement : "je désigne l'instance de la classe englobante de cette classe anonyme interne".
                MedicamentBDD medicamentBDD = new MedicamentBDD(this);
                medicamentBDD.open();
                Medicament medoc = medicamentBDD.getMedicamentWithId(0);
        }
    });
    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

  15. #15
    Membre éclairé Avatar de kratoce
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2012
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2012
    Messages : 270
    Par défaut
    Si j'ouvre ma bdd en final, avant le button, avec this, pourquoi je plante (en utilisant cette objet dans mon button) alors que le context n'est pas celui de la classe anonyme interne créée mais de la classe englobante ?

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/02/2017, 15h02
  2. Réponses: 1
    Dernier message: 10/09/2008, 16h04
  3. JDBC: Result set already closed
    Par kidjeri dans le forum JDBC
    Réponses: 5
    Dernier message: 27/04/2006, 17h54
  4. Réponses: 8
    Dernier message: 21/11/2003, 18h38

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