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 :

[LayoutInflater] Out of memory


Sujet :

Android

  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 385
    Par défaut [LayoutInflater] Out of memory
    Bonjour ,

    Me voici encore confronté à un souci .. !
    Suite à mon précédent topic : [ListView] Adapater / NullPointerException , page 2 , on ma conseiller une technique pour afficher les enregistrements par paquet (10 à 10 etc ... ) avec un bouton de suite . !

    J'ai donc déduit qu'on parlais d'un LayoutInflater, j'ai donc créer mes expandableList...

    Bon maintenant le cœur du sujet :
    1 - Cela marche quand je le fait de manière STATIQUE ! Avec une chaine de string...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public ExpandableAdapterBis(Context _context, String[] _array, int _pagination) {
    		mArray=_array;
            mContext=_context;
            pagination=_pagination;
            current_page=1;
            mInflater =LayoutInflater.from(_context);
    	};
    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
    private String[] mArray=new String[] {
        	    "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
        	    "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
        	    "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
        	    "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
        	    "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
        	    "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
        	    "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
        	    "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
        	    "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
        	    "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
        	    "Cook Islands", "Costa Rica", "Croatia", "Cuba"
        	  };	
    @Override
    	 public void onCreate(Bundle savedInstanceState) {
    	        super.onCreate(savedInstanceState);
    	        setContentView(R.layout.second);
     
    	        mListView=(ListView)findViewById(R.id.listView1);
    	        mExpandableAdapter = new ExpandableAdapterBis(this, mArray, 11);
    	        mListView.setAdapter(mExpandableAdapter);
    2 - L'adaptation de mon Arraylist dans celui ci ne marche pas ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	public ExpandableAdapterBis(Context _context, ArrayList<String> personnes,
    			int _pagination) {
    		// TODO Auto-generated constructor stub
    		mContext=_context;
            pagination=_pagination;
            current_page=1;
            mInflater =LayoutInflater.from(_context);
    	}
    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
    	 public void onCreate(Bundle savedInstanceState) {
    	        super.onCreate(savedInstanceState);
    	        setContentView(R.layout.second);
     
    	        /*mListView=(ListView)findViewById(R.id.listView1);
    	        mExpandableAdapter = new ExpandableAdapterBis(this, mArray, 11);
    	        mListView.setAdapter(mExpandableAdapter);*/
     
     
     
    	        DatabaseHelper dbh;
    			try {
    				dbh = new DatabaseHelper(this.getApplicationContext()); 
    mListView=(ListView)findViewById(R.id.listView1);
    mExpandableAdapter = new ExpandableAdapterBis(this,dbh.getPersonnes(), 11);
    mListView.setAdapter(mExpandableAdapter);
     
    			} catch (IOException e) {
    				e.printStackTrace();
    			}

    Merci à vous ,
    Toujours des topics à ce tirer les cheveux...

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2010
    Messages
    394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Avril 2010
    Messages : 394
    Par défaut
    Le fait que dans le constructeur de ExpandableAdapterBis il n'y ait pas de référence à ton ArrayList<String> personnes est dû à une faute de frappe (sinon, c'est normal que ça ne fonctionne pas...).

    Sinon, qu'entends-tu exactement par "ça ne marche pas" ? L'appli plante ? Elle affiche n'importe quoi ? Il ne se passe rien ?

    Mako.

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 385
    Par défaut
    mon getPersonnes() ce trouve dans mon DatabaseHelper.

    Pour "ça ne marche pas" , oui j'ai oublier de redire , mais cela est dans le titre : J'ai un "Out of memory on a 1191496-byte allocation" ce qui m'indique que mes processus doivent dépasser les 24MB :S ! (encore ... )

    Je travail sur une table de 33k enregistrement sur 5colonnes.

    Pour mon getPersonnes() , ce trouvant dans mon DatabaseHelper le voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public ArrayList<String> getPersonnes() {
        ArrayList<String> output = new ArrayList<String>();
        String[] colonnesARecup = new String[] { "nom", "prenom" };
        Cursor cursorResults = mydb.query(TABLE_LISTELEC, colonnesARecup, null,
                null, null, null, "nom asc, prenom asc", null);
    	while (cursorResults.moveToFirst())
    	{
    		output.add(cursorResults.getString(0) + " " + cursorResults.getString(1));
    	}				
        return output;
    }
    L'erreur complète :

    Out of memory on a 1191496-byte allocation
    ......
    ......
    FATAL EXCEPTION : main
    java.lang.OutOfMemoryError
    at com.listexpendable.DatabaseHelper.getPersonnes(DatabaseHelper.java:150)
    com.listexpendable.List.onCreate(List.java:45)
    La ligne : (DatabaseHelper.java:150), correspond à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    output.add(cursorResults.getString(0) + " " + cursorResults.getString(1));
    La ligne : (List.java:45), correspond à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mListView.setAdapter(mExpandableAdapter);
    et oui au final elle plante... avec le classique sorry etc !

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2010
    Messages
    394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Avril 2010
    Messages : 394
    Par défaut
    De base, vu la tête de l'erreur, je dirais que la volumétrie de résultats est trop importante. Peut-être que cela vient de la requête effectué, et du volume de résultat obtenu (et j'insiste sur le peut-être...).

    Il faudrait sans doute essayer d'en savoir un peu plus en ajoutant des logs (nombre d'itérations avec plantage entre autres).

    Sinon, désolé, je n'ai pas plus d'idées.

    Mako.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 385
    Par défaut
    Oui le volume total à traiter est très important et c'est pour cela que je ne peu le traiter dans une listView classique , normalement un LayoutInflater sert à faire les appel par bloque de demande (ici 10 par 10) , ce qui me semblais être la technique la plus adéquate pour pouvoir quand même afficher mes données ... !

    Merci en tout cas pour ton aide qui a surement permis de mieux éclaircir le problème !

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2010
    Messages
    394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Avril 2010
    Messages : 394
    Par défaut
    En l'occurrence, j'ai l'impression que tu vas charger tous tes résultats en une seule fois (requête SQL), mais que l'affichage lui, se fera par bloc. Or actuellement, ce n'est pas au niveau de l'affichage que tu as des soucis de capacité, mais plutôt au niveau de la récupération de tes données.

    Ne serait-il pas possible de les charges par bloc ?

    Mako.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

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


    Ne serait-il pas possible de les charges par bloc ?
    Je pensais que cela se faisais comme sa , les livres et les formations Video2brain ne sont que sur des exemples statiques ... :S !

    Ton idée étais pas mauvaise je pense sur le fond j'ai fait donc une modification dans mon code ... (j'appellais deux chaine de String (Nom & prenom) du coup j'ai garder que les nom... !

    Mais j'ai toujours un problème de mémoire :S !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public ArrayList<String> getPersonnes() {
        ArrayList<String> output = new ArrayList<String>();
        String[] colonnesARecup = new String[] { "nom"};
        Cursor cursorResults = mydb.query(TABLE_LISTELEC, colonnesARecup, null,
                null, null, null, "nom asc",null);
    	while (cursorResults.moveToFirst())
    	{
    		output.add(cursorResults.getString(0));
    	}				
        return output;
    }
    Mais c'est bizarre j'ai une erreur encore plus "lourd" en poids o_o !
    Clamp target GC heap from 33.750MB to 32.000MB
    Out of memory on a 2680844-byte allocation.
    Les erreurs se trouves maintenant sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     mExpandableAdapter = new ExpandableAdapterBis(this,dbh.getPersonnes(), 11);
    et :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    output.add(cursorResults.getString(0));
    Merci je suis preneur de toutes idées !

  8. #8
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour,

    Au vu de tes messages essaye plutôt de regarder comment évolue ta mémoire , soit en la loggant soit en regardant dans le DDMS ?

    Peut être d'autre composant te prenne également pas mal de mémoire et non seulement cette fonctionnalité ?

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

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

    Merci de ta réponse ,

    Concernant :
    Au vu de tes messages essaye plutôt de regarder comment évolue ta mémoire , soit en la loggant soit en regardant dans le DDMS ?
    Je regarde bien dans le DDMS (logCat) et ce que je remarque c'est qu'il essaye de me prendre TOUS les enregistrements au lieu de seulement les 10premiers (comme mon code le demande )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     mExpandableAdapter = new ExpandableAdapterBis(this,dbh.getPersonnes(), 11);
    Alors que une ExpandableList avec un LayoutInflater ne devrais t'il pas faire du requêtage par "paquet" plutôt que en global ? (enfin c'est ce que explique la formation Video2brain et les cours online).

    Je ne comprend pas trop d'où peut venir le problème... enfin , je pense que le souci peu éventuellement ce situer au niveau de mon Cursor :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public ArrayList<String> getPersonnes() {
        ArrayList<String> output = new ArrayList<String>();
        String[] colonnesARecup = new String[] { "nom"};
        Cursor cursorResults = mydb.query(TABLE_LISTELEC, colonnesARecup, null,
                null, null, null, "nom asc",null);
    	while (cursorResults.moveToFirst())
    	{
    		output.add(cursorResults.getString(0));
    	}				
        return output;
    Qui , comme la fait remarquer @Mako 5013 pourrais forcer à une selection global sans faire "l'écrémage" des 10record ... !

    Sinon pour :
    Peut être d'autre composant te prenne également pas mal de mémoire et non seulement cette fonctionnalité ?
    J'ai diviser mon application en plusieurs projet pour évité les soucis entre les actions , je ferais le travail de connexion après.
    Actuellement dans ce projet-annexe , je n'est que Deux parties :
    - Import de la bdd via Assets
    - Affichage des données dans un ExpandableListView
    (En tout cela représente 7 class Java, donc assez correct)

    Je suis preneur de toute idées , simple ou farfelu, l'important pour moi est la compréhension et la résolution de ce problème.

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    385
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 385
    Par défaut
    Donc après quelques test , il semblerais que cela vienne d'une fuite mémoire assez ... conséquente ^^ !! J'ai donc vérifier certaines choses , rajouter un close sur mon cursor après ma requête , mais il semblerais que ce soit la Database (ici : npb.sqlite) qui ne soit pas fermé de façon explicite ...

    Edit (j'ai oublier de mettre l'erreur logcat) :
    close() was never explicitly called on database '/data/data/com.listexpandable/databases/npb.sqlite'
    android.database.sqlite.DatabaseObjectNotClosedException : Application did niot close the cursor or database object that was opened here ...
    Et il me cite la ligne : 73 & 44 de DatabaseHelper et la ligne : 42 de List.java qui correspondent dans l'ordre :
    DatabaseHelper.java ligne 44 :
    ligne 73 :
    List.java ligne 42 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dbh = new DatabaseHelper(this.getApplicationContext());
    Si quelqu'un peu dénicher ou j'ai rater de mettre la fermeture de la base , j'en serais fortement reconnaissant et soulager ^^ (en espérant que tout mes soucis vienne de là ... ):

    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
     
    public class DatabaseHelper extends SQLiteOpenHelper{
     
        private String DB_PATH;
     
        private static String DB_NAME = "npb.sqlite";
        private static final Integer DB_VERSION = 2;
     
        private static String TABLE_LISTELEC = "npb";
        private SQLiteDatabase mydb; 
     
        private final Context myContext;
     
        public DatabaseHelper(Context context) throws IOException {
     
            super(context, DB_NAME, null, DB_VERSION);
            this.myContext = context;
            DB_PATH = "/data/data/com.listexpendable/databases/";
     
            createDataBase();
        }   
     
        @Override
        public void onCreate(SQLiteDatabase db) {
     
        }
        public void onOpen(SQLiteDatabase db){}
     
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
     
     
     
    public void createDataBase() throws IOException{
        boolean dbExist = checkDataBase();
        if(dbExist){
        }else{
                this.getReadableDatabase();
                try {
                        copyDataBase();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
        openDatabase();
    }
     
    private void copyDataBase() throws IOException{
     
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
     
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
     
        //Close the streams
        myOutput.close();
        myOutput.flush();   
        myInput.close();
    }
     
     
     
    public void openDatabase() throws SQLException {
    	//Open the database
    Log.i("test","on va instancier mydb");
       String myPath = DB_PATH + DB_NAME;
    	mydb = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    Log.i("test","mydb="+mydb);
    }
     
     
    private boolean checkDataBase(){
     
        SQLiteDatabase checkDB = null;
     
        try{
                String myPath = DB_PATH + DB_NAME;
                checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
     
        }catch(SQLiteException e){
     
                //database does't exist yet.
     
        }
     
        if(checkDB != null){
     
                checkDB.close();
     
        }
     
        return checkDB != null ? true : false;
    } 
     
    @Override
        public synchronized void close() {
            if(mydb != null)
                mydb.close();
            super.close();
        }
     
    public ArrayList<String> getPersonnes() {
        ArrayList<String> output = new ArrayList<String>();
        String[] colonnesARecup = new String[] { "nom", "prenom" };
        Cursor cursorResults = mydb.query(TABLE_LISTELEC, colonnesARecup, null,
                null, null, null, "nom asc",null);// prenom asc", null);
    	while (cursorResults.moveToFirst())
    	{
    		output.add(cursorResults.getString(0) + " " + cursorResults.getString(1));
     
    	}	
        cursorResults.close();
        return output;
     
    }
    }
    Et mon List.java (au cas ou ce soit ici qu'il faille faire la fermeture) :

    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
    public class List extends Activity{
    	private ListView mListView;
    	private ExpandableAdapterBis mExpandableAdapter;	
    @Override
    	 public void onCreate(Bundle savedInstanceState) {
    	        super.onCreate(savedInstanceState);
    	        setContentView(R.layout.second);
     
    	        DatabaseHelper dbh;
    			try {
    				dbh = new DatabaseHelper(this.getApplicationContext());
    				 mListView=(ListView)findViewById(R.id.listView1);
    				  mExpandableAdapter = new ExpandableAdapterBis(this,dbh.getPersonnes(), 11);
    	        	  mListView.setAdapter(mExpandableAdapter);
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
     
     
    	        ((Button) findViewById(R.id.back)).setOnClickListener(new OnClickListener() {
    	public void onClick(View v) {
    		finish();
    				}
    	        });
    }
    }

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

Discussions similaires

  1. [XStream][String]out of memory
    Par Invité dans le forum Persistance des données
    Réponses: 8
    Dernier message: 10/01/2006, 14h52
  2. [C++] [gcc] out of memory
    Par fxp17 dans le forum GCC
    Réponses: 5
    Dernier message: 06/01/2006, 10h29
  3. [pb mémoire] out of memory d'eclipse
    Par Casp dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 12/05/2005, 16h39
  4. Out of memory
    Par shurato dans le forum ANT
    Réponses: 1
    Dernier message: 10/11/2004, 16h19
  5. [JBuilder 8] Out of memory problem ...
    Par keros dans le forum JBuilder
    Réponses: 2
    Dernier message: 08/09/2003, 19h03

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