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 :

Problème d'accès à un singleton


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 55
    Par défaut Problème d'accès à un singleton
    Bonjour,

    Je vous explique mon problème.

    Je voudrais prendre capturer une photo pendant le streaming.
    Donc dans la méthode "onPreviewFrame" je viens regarder si un flag est à "true" pour capturer la photo.
    Et dans mon "Service" quand je reçois un message de mon webService, je met le flag à "true".

    Voici ma classe singleton:
    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
    31
    32
    33
    34
    35
    36
    37
    public class CameraManager {
     
    	private static String TAG = "CameraManager";
     
    	private static CameraManager instance = null;
     
    	private boolean shouldTakePicture = false;
     
    	private String classA = null;
     
    	private CameraManager(String classA) {
    		this.classA = classA;
    	}
     
    	public static CameraManager getInstance(String classA) {
    		Log.d(TAG, "cameraManager - getInstance -" + classA);
    		 if (CameraManager.instance == null) {
    			 Log.d(TAG, "cameraManager - instance == null - " + classA);
    	            synchronized(CameraManager.class) {
    	              if (CameraManager.instance == null) {
    	            	  CameraManager.instance = new CameraManager(classA);
    	              }
    	            }
    	         }
    	         return CameraManager.instance;
    	}
     
    	public synchronized boolean isShouldTakePicture() {
    		Log.d(TAG, "cameraManager - shouldTakePicture: " + shouldTakePicture + " - " + classA);
    		return shouldTakePicture;
    	}
     
    	public synchronized void setShouldTakePicture(boolean shouldTakePicture) {
    		this.shouldTakePicture = shouldTakePicture;
    		Log.e(TAG, "cameraManager - shouldTakePicture: " + shouldTakePicture + " - " + classA);
    	}
    }
    J'ai mis volontairement beaucoup de logs.

    Voici les logs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    04-05 12:37:33.890: D/CameraManager(1549): cameraManager - getInstance -InfosSession
    04-05 12:37:33.890: D/CameraManager(1549): cameraManager - instance == null - InfosSession
    04-05 12:37:34.350: D/CameraManager(1549): cameraManager - getInstance -VideoCaptureAndroid
    04-05 12:37:35.560: D/CameraManager(1549): cameraManager - shouldTakePicture: false - InfosSession
    04-05 12:37:35.640: D/CameraManager(1549): cameraManager - shouldTakePicture: false - InfosSession
    ....
    04-05 12:37:59.900: D/CameraManager(1549): cameraManager - shouldTakePicture: false - InfosSession
    04-05 12:37:59.950: E/CameraManager(1529): cameraManager - shouldTakePicture: true - InfosSession
    04-05 12:37:59.980: D/CameraManager(1549): cameraManager - shouldTakePicture: false - InfosSession
    04-05 12:38:00.080: D/CameraManager(1549): cameraManager - shouldTakePicture: false - InfosSession
    04-05 12:38:00.130: D/CameraManager(1549): cameraManager - shouldTakePicture: false - InfosSession
    ...
    Comme vous pouvez le constater, le flag est bien mis à "true" par mon "Service" mais la valeur récupérer dans la méthode "onPreviewFrame" est toujours à "false".

    Je ne vois pas d'où vient mon problème.

    Merci,
    Drlord.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 96
    Par défaut
    Bonjour,

    Ton singleton n'est pas thread-safe voir : http://christophej.developpez.com/tu...n/multithread/

    Du coup, il faudrait vérifier si tu as une ou plusieurs instances de CameraManager et quelle est l'instance qui est exécutée.

    C'est quoi le chiffre qui est entre paranthéses dans tes log ?


    S. Combes

  3. #3
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 55
    Par défaut
    Le chiffre entre parenthèse correspond au PID de l'application.

    Sinon pour revenir à mon problème de thread et singleton, il me semble que dans les logs on constate bien que c'est la même instance du Singleton qui est utilisé.
    A chaque fois que fais appel à la méthode "getInstance" je lui envoie comme paramètre le nom de la classe où se fait l'appel. ET je sauvegarde ce paramètre s'il y a création du singleton. Etant donné que c'est "InfosSession" qui est la première classe à faire appel à mon singleton, c'est ce paramètre qui est affiché à chaque fois.
    Enfin c'est en tout ce que j'ai essayer de vérifier en utilisant ce paramètre...

    J'ai essayer d'utiliser la méthode décrite dans le point "3.2.1. La synchronisation de getInstance()" mais j'obtient le même résultat.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 96
    Par défaut
    J'ai testé ta classe en modifiant quelque peu le code afin de pouvoir le faire fonctionner :
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    public class CameraManager {
     
    	private static String TAG = "CameraManager";
     
    	private static CameraManager instance = null;
     
    	private boolean shouldTakePicture = false;
     
    	private String classA = null;
     
    	private CameraManager(String classA) {
    		this.classA = classA;
    	}
     
    	public static CameraManager getInstance(String classA) {
    		System.out.println("cameraManager - getInstance -" + classA);
    		 if (CameraManager.instance == null) {
    			 System.out.println("cameraManager - instance == null - " + classA);
    	            synchronized(CameraManager.class) {
    	              if (CameraManager.instance == null) {
    	            	  CameraManager.instance = new CameraManager(classA);
    	              }
    	            }
    	         }
    	         return CameraManager.instance;
    	}
     
    	public synchronized boolean isShouldTakePicture() {
    		System.out.println("cameraManager - shouldTakePicture: " + shouldTakePicture + " - " + classA);
    		System.out.println(this);
    		return shouldTakePicture;
    	}
     
    	public synchronized void setShouldTakePicture(boolean shouldTakePicture) {
    		this.shouldTakePicture = shouldTakePicture;
    		System.out.println("cameraManager - shouldTakePicture: " + shouldTakePicture + " - " + classA);
    		System.out.println(this);
    	}
    }
    Le test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class Main {
     
    	public static void main(String[] args) {
    		CameraManager c = CameraManager.getInstance("CameraManager");
    		c.isShouldTakePicture();
    		c.setShouldTakePicture(true);
    		c.isShouldTakePicture();
    	}
    }
    Donne les résultats :
    cameraManager - getInstance -CameraManager
    cameraManager - instance == null - CameraManager
    cameraManager - shouldTakePicture: false - CameraManager
    CameraManager@9304b1
    cameraManager - shouldTakePicture: true - CameraManager
    CameraManager@9304b1
    cameraManager - shouldTakePicture: true - CameraManager
    CameraManager@9304b1
    La classe semble fonctionner correctement.
    Par contre je pense que ton Singleton n'est toujours pas thread-safe (mais je ne sais pas les modification qu'il faudrait apporter pour qu'il le soit).
    En effet, il est possible de créer une instance de CameraManager par introspection sans passer par le getInstance.
    Voir ce sujet où j'ai présenté un test simple qui montre la chose : http://www.developpez.net/forums/d12...ler-singleton/

    Pour t'assurer que tu utilise la même instance de ton objet CameraManager ajoute les "System.out.println(this);" comme dans le code que j'ai donné


    S. Combes

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 55
    Par défaut
    Merci.

    J'ai suivi ton conseil et j'ai constater qu'il y a bien un problème avec mon singleton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    04-05 16:02:45.700: D/CameraManager(28134): cameraManager - shouldTakePicture: false - InfosSession
    04-05 16:02:45.700: D/CameraManager(28134): cameraManager: com.csipsimple.utils.CameraManager@407a3198
    04-05 16:02:45.720: E/CameraManager(28110): cameraManager - shouldTakePicture: true - InfosSession
    04-05 16:02:45.720: E/CameraManager(28110): cameraManager: com.csipsimple.utils.CameraManager@407b4e40
    04-05 16:02:45.760: D/CameraManager(28134): cameraManager - shouldTakePicture: false - InfosSession
    04-05 16:02:45.760: D/CameraManager(28134): cameraManager: com.csipsimple.utils.CameraManager@407a3198
    Donc j'ai au moins pu tirer un enseignement, mon idée pour savoir s'il y avait une ou deux instance de mon singleton était incorrect.

    Bon sinon pour revenir à mon problème, je ne vois pas trop comment le résoudre.
    Je peux par contre peut être détailler un peu plus l'architecture du projet.
    Le singleton ainsi que la classe où il y a la méthode "onPreviewFrame" est dans une librairie. Et le "Service" est dans mon application principale.

    Je vais essayer de trouver une solution en essayant de comprendre pourquoi j'ai 2 instance de mon singleton...
    Mais je suis ouvert à des propositions

  6. #6
    Expert confirmé

    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
    Billets dans le blog
    3
    Par défaut
    Peut etre parcequ'il y a deux instances du process:
    28134 et 28110

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

Discussions similaires

  1. [ADO] [MSACCESS] Problème d'accès à une table nommée OF
    Par FredRaid dans le forum Bases de données
    Réponses: 3
    Dernier message: 15/02/2005, 17h22
  2. Problème d'accès à une DB
    Par Mvu dans le forum ASP
    Réponses: 4
    Dernier message: 04/01/2005, 11h36
  3. [TOMCAT] JSP problème d'accès aux méthodes d'une classes
    Par gunnm dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 22/05/2004, 14h02
  4. problème d'acces concurentiel à un fichier
    Par Theoden dans le forum MFC
    Réponses: 2
    Dernier message: 04/03/2004, 09h49

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