Travaux Pratiques,

Thread, AsyncTask

Thème: Une liste est chargée en tâche de fond... et une première utilisation de l'enregistreur de tests Espresso

 

 

Question1) Chargement d'une liste d'items à partir d'un fichier

Plusieurs documents sont disponibles sur le site de l'INSEE, dont la liste des cantons, proposer une application permettant en tâche de fond, à l'aide d'une instance de la classe prédéfinie AsyncTask, de charger ce fichier dans une liste dont chaque item est le nom d'un canton, au clic sur un nom de canton, un toast apparaît avec le code postal...

 

Mise en oeuvre, préambule,

    Créez le dossier assets sous AndroidStudio,(File > New > folder > assets Folder) à ce lien une façon de faire

    Placez ce fichier canton2015.csv.txt dans le répertoire assets créé, ce fichier est au format CSV: un ';' sépare chaque item, les noms des colonnes sont en première ligne

 

L'IHM est constituée d'une liste, de 3 boutons et d'une barre de progression

  • La liste recevra tous les cantons (environ 2000),
  • Le bouton Load commence le chargement en tâche de fond, ligne par ligne, celui-ci est ralenti par un délai (SystemClock.sleep(100); )
     en fonction de votre périphérique, un délai afin d'avoir le temps de stopper ce chargement.
    
                      L'arrêt et la reprise du chargement sont effectués par les boutons Stop et Resume 
                         (Deux fonctionnalités demandées en question 2)
  • La barre de progression indique l'état du téléchargement.
 
Un layout possible ...
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         
   
    android:layout_width="fill_parent"
   
    android:layout_height="fill_parent">
             <TableRow
       
        android:id="@+id/tableRowId"
                 
       
        android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:layout_alignParentBottom="true">
                      <Button
           
            
                  android:layout_width="wrap_content"
                 
           
            android:layout_height="wrap_content"
                  android:text="Load"
                  android:id="@+id/loadBtnId"
                  android:onClick="onClickLoad"/>
                      <Button
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Stop"
                  android:id="@+id/stopBtnId"
                  android:onClick="onClickStop"/>
                      <Button
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Resume"
                  android:id="@+id/resumeBtnId"
                  android:onClick="onClickResume"/>
                      <ProgressBar
                 
           
            style="?android:attr/progressBarStyleHorizontal"
                  android:layout_width="fill_parent"
                  android:layout_height="match_parent"
                  android:layout_centerHorizontal="true"
                  android:layout_centerVertical="true"
                  android:layout_marginLeft="10dp"
                  android:layout_marginRight="10dp"
                  android:id="@+id/progressBarId"
                  android:max="2000"
                  android:indeterminate="false" />
                      </TableRow>
                    <ListView
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"
                 android:layout_alignParentTop="true"
                 android:stackFromBottom="true"
                 android:transcriptMode="alwaysScroll"
                 android:id="@android:id/list"
                 android:layout_above="@id/tableRowId"/>
</RelativeLayout>
 

 Un extrait d'une possible lecture du fichier au sein de la méthode doInBackground (cf. AsyncTask)

    try {
      InputStreamReader isr = new InputStreamReader(getAssets().open(FILE_NAME),"ISO_8859_1"); // StandardCharsets.ISO_8859_1);
      LineNumberReader lnr = new LineNumberReader(isr);
           
     
        // à compléter en q2
          String s = null;
      while ((s = lnr.readLine()) != null 
    && true
    /* à compléter en q2 */ ){
            publishProgress(s);          // à chaque ligne lue depuis le fichier, la liste est réactualisée
        SystemClock.sleep(100);       // délai en fonction des performances du périphérique Android
          }
          lnr.close();
          isr.close();
        }catch(Exception e){
           if(I)Log.i(TAG,"Exception: " + e.getMessage());
        }
 
Le  nombre de lignes d'un fichier,
      nécessaire afin d'initialiser correctement la barre de progression, peut être obtenu par cet extrait de code
LineNumberReader   lnr =  new LineNumberReader(newFileReader(newFile("File1")));
    lnr.skip(Long.MAX_VALUE);
    System.out.println(lnr.getLineNumber()+1);  
    // Add 1 because line index starts at 0
    // Finally, the LineNumberReader object should be closed to prevent resource leak  
    lnr.close();
source:http://stackoverflow.com/questions/453018/number-of-lines-in-a-file-in-java
Attention ce code doit être exécuté en tâche de fond,  une sous classe d'AsyncTask
 

Question2) Arrêt et reprise du chargement

Deux boutons Stop et Resume permettent d'interrompre le chargement et de reprendre celui-ci

    La copie a pris un peu de temps, alors quelques cantons ont été affichés entre Saint-Etienne-du-bois et Souvigny ...

 

 

Question3) Tests unitaires, usage de l'enregistreur Espresso

    Préambule : suivez cette mise en ouvre et visionner la vidéo à cette page https://developer.android.com/studio/test/espresso-test-recorder.html

    Proposer une classe de tests unitaires, minimale pour ce tp, juste pour une prise en main de cet enregistreur.  

            https://developer.android.com/training/testing/index.html

 

Question4) Optionnelle) L'application des questions 1 et 2 avec les fragments dont ListFragment

    Une idée d'IHM : L'écran en deux fragments, à gauche les commandes Load, Stop et Resume et à droite la liste des cantons...