🍦Android Basics

🍦Android Basics

Glossaire collaboratif

A vous de compléter ce glossaire, nous avons déjà mis quelques mots à définir, mais c'est votre glossaire de promo, ajouter ce que vous voulez d'utile. Ce document sera autorisé lors de l'examen.

Glossaire Android DIM 2022 - HackMD
:::info **A vous de compléter ce glossaire, nous avons déjà mis quelques mots à définir, mais c’es

Les Codelabs

L'API Android change souvent, vous allez le constater car même la documentation officielle va vous fournir du code obsolète parfois. Il faut faire avec.

On va utiliser des codelabs tout au long du workshop, des genre de tutoriels très guidés rédigés par les ingénieurs de chez Google .

Cela a deux gros avantages :

  • Ils sont à jour
  • Ils apportent les bonnes pratiques officielles de Google pour Android

Pour ne pas vous perdre dans tous les codelabs voici la table des matières

Codelabs for Android Kotlin Fundamentals | Training Courses

Les concepts de base

Getting started

  1. Commencez par télécharger Android Studio à cette adresse : https://developer.android.com/studio
  2. Suivez le tutoriel Google suivant : https://codelabs.developers.google.com/codelabs/kotlin-android-training-get-started/#0
  3. Faites valider votre Hello world et les réponses aux questions suivantes par l'enseignant.
Question 1 👉 Qu'est ce que AVD ? Que faut-il faire pour utiliser votre smartphone en tant qu'appareil de test pour votre app ?
Question 2 👉 A quoi servent les fichiers / dossiers suivants :
  • 🗂 layout
  • 🗂 values
  • 🗂 drawable
  • 📄 strings
  • 📄 colors
  • 📄 styles
  • 🗂 java
  • 🗂 generatedJava ?
  • 🗂 Le fichier AndroidManifest.xml ?

Tester son app

Le SDK Android vous permet aussi de pouvoir tester vos applications (c’est quand même mieux) sur un émulateur très complet.

Il vous permettra d’émuler :

  • Un type d’appareil particulier
  • Des résolutions différentes
  • Des positions GPS, la caméra, etc.
  • Des orientations, etc.

Alors n'hésitez pas à l'utiliser pour vos tests, attention il consomme énormément de CPU ce qui peut être gênant sur des config modestes.

Note ⚠️: L'émulateur utilise la virtualisation native de votre processeur, n'espérez pas l'utiliser si vous travaillez déjà sur une machine virtuel.

Gradle

Comme vous l'avez sûrement remarqué la compilation d'un projet Android utilise Gradle pour fonctionner.

Gradle va permettre de compiler pas mal d'éléments à votre place afin que vous ayez tous les outils à disposition directement dans votre code sans vous en soucier.

Note 📝 : Gradle va notamment compiler les interfaces XML en bytecode accessibles par votre code, s'occuper de gérer les assets et les rendre accessibles, dupliquer les images pour différentes tailles d'appareil, et beaucoup beaucoup d'autres choses.

Nous reviendrons sur le fichier build.gradle vous aurez a y mettre les pieds de temps en temps.

Le View Binding

📣 Règle de base avant d'aller plus loin
Utilisez l'autocomplétion d'Android Studio et utilisez la documentation. Le framework est vaste, et personne n'apprend par coeur les variables et constantes (notamment dans les XML). Android Studio est essentiel pour être efficace. Utilisez le à FOND.

Grâce au tutoriel vous savez comment le projet est structuré. Mais maintenant il serait interessant de pouvoir interagir avec l'utilisateur a travers l'interface, lier le code au XML, comme le JS permet d'agir avec le HTML pour proposer à l'utilisateur un moyen d'agir sur les données dans l'idée.

On va pouvoir faire cela avec le View Binding. Dans le framework Android c'est le fait de lier la définition de l'interface de l'application au code. Cela permet au code de modifier l'interface dynamiquement et à l'interface d'envoyer des informations de saisies au code par exemple.

Auparavant (en Java) le View Binding entre l'interface XML et le Code Java se faisait en effectuant ce genre d'opération dans votre activité :

public class MainActivity extends AppCompatActivity {

    //Créer une propriété 
    private Button mButton;
    private TextEdit mTextField;
    private TextView mTextView;
    private Slider mSlider;
    //etc.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //Instancier notre propriété en allant récuperer la représentation dans le fichier `R`
        //de notre bouton, après que le XML ait été inflate via Gradle.
        mButton = findViewById(R.id.my_button_id);
        mTextField = findViewById(...);
        mTextView = findViewById(...);
        mSlider = findViewById(...);
       //etc.
    }
Imaginez la taille des onCreate pour une interface de formulaire !

Avec Kotlin et le Jetpack View Binding voici le code équivalent :

//Rien.
class MainActivity : AppCompatActivity() {
    private lateinit var binding: FragmentGameOverBinding
    
    override fun onCreateView(...): View? {
    // Inflate the layout for this fragment
    val binding = inflater.inflate(R.layout.fragment_game_over, container, false)
        viewModel.getGameOverValues().observe(this, Observer { updateUi(it) })
        return binding.rootView
    }
  	
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 	{
        binding.retryButton.setOnClickListener {
           //action
    }
 }

On a besoin de faire le binding une seule fois dans onCreate ensuite on utilise n'importe quel view en utilisant la variable binding. Pas besoin de créer sois-même autant de variable qu'il a de vue dans votre XML, pratique.

Pour en savoir plus sur l'implémentation du ViewBinding : https://developer.android.com/topic/libraries/view-binding

Question 3 👉 Pour expérimenter tout cela du bout de vos doigts, réalisez la leçon 2 du Codelabs puis faites valider par l'enseignant.
+ d'infos : https://developer.android.com/courses/kotlin-android-fundamentals/toc
Question 4 👉 Comment faites vous pour que le click d'un bouton sur l'interface lance une fonction de votre code ? Quel concept de la programmation objet est utilisé dans ce cas ?

Activité et Intent

Votre application sous Android est composé d'Activité(s) et/ou de service(s).

Les activités sont des composants permettant d'afficher une interface à l'utilisateur.

On peut lancer une activité uniquement en lançant ce qu'on appelle un intent.

Par défaut votre app est créée avec une Activité MainActivity mais rien ne vous empêche de changer le nom. Il faudra juste changer le nom également dans le AndroidManifest.xml de votre application.

Chaque Activity possède un équivalent XML, qui représente son interface.

L'interface

L'interface peut-être définie soit par du code pur, soit par le biais d' XML, voyez cela comme votre page HTML lorsque vous faite du web et votre code Kotlin comme du Javascript qui agit sur la vue.

Il existe beaucoup de composants natifs et additionnels pour composer votre interface, je ne vais pas les détailler précisément.

Mais vous pouvez explorer les différents éléments dans la "palette" de l'éditeur d'interface d'une de vos activité.

Question 5 👉 Faites un peu de recherche sur les différents composants disponibles et leurs propriétés. Et réalisez l'interface suivante uniquement en XML en utilisant les linear layouts. (Vous êtes libre sur les couleurs). "Same day messenger service" est un toast.

Question 6 👉 Réalisez cette interface en utilisant des constraints layouts

Pour vous aider : Layouts Codelabs

Les fragments

Un fragment sous Android est un composant d'interface qui s'intègre dans une Activity.
Un fragment possède son propre cycle de vie qui est dépendant du cycle de vie de l'activity qui l'héberge.

Il est en quelque sorte une "sous activité" qui peut contenir de la logique et est relié également à un XML d'interface.

Une activité contenant 2 fragment

Imaginez un fragment comme l'équivalent d'un component en VueJS, React ou Svelte.

Les fragments étaient autrefois peu utilisés sur Android, on utilisait presque une activité par écran. Aujourd'hui c'est l'inverse, on évite d'avoir plus d'une ou deux activity dans son app. On préfèrera avoir beaucoup de fragment plus maléables et réutilisables.

Expérimentez en réalisant les tutoriels suivants sur codelabs :

Question 7 👉 Que signifie le fait d'inflate l'interface lors de l'instanciation du fragment ?
Question 8 👉 Quel est l'équivalent Jetpack de la bibliothèque com.android.support:design que vous avez dû utiliser ? Comment avez vous trouvé cette information ?
Question 9 👉 Qu'est ce qui vous permet de facilement créer un chemin de navigation dans votre application ? Détaillez le processus.
Question 10 👉 Faites valider par l'enseignant la réalisation des codelabs et les réponses aux questions.

Le Lifecycle (ou cycle de la vie 🦁)

Le lifecycle est un concept qui existe partout en programmation, il faut particulièrement bien le connaitre et l'utiliser au mieux lors du développement d'application sur mobile.

Votre application a besoin de garder un état et peut se faire stopper par tout et n'importe quoi sur un smartphone : Un appel, une notification ouverte pour une autre app, la batterie qui s'épuise, le manque de réseau etc. etc.

Il faut avant tout penser, qu'un téléphone sert à... téléphoner. Donc la règle numéro un quand on fait du développement mobile c'est de penser qu'à tout moment le téléphone doit être disponible pour recevoir un appel. Ce qui veut dire deux choses :

  • Une application est susceptible d'être coupée à tout moment
  • Une application doit consommer le moins de ressources possibles pour ne pas gêner le fonctionnement normal du téléphone.

Pour réagir à cela chaque application dispose d'un cycle de vie et comme nous l'avons vu dans les basics, il faut savoir composer avec le cycle de vie de l'application, de l'activité ou du fragment.

Le lifecycle est tellement central et complexe à gérer que Google a fait quelque chose pour aider les développeurs Android a s'éviter le plus possible de tomber dans cette complexité.

Pourquoi ça devient complexe ? ⬇️️️  ⬇️️️  ⬇️️️

oh pour rien

Ce n'est qu'un exemple, mais vous allez rapidement vous en rendre compte lors de vos développements.

Rappel et explication du cycle de vie d'une activité :

Quand une application se lance, l'activité principale de l'application se charge (<action android:name="android.intent.action.MAIN" />).

La méthode onCreate se lance. C'est l'occasion pour vous de construire votre UI et d'initialiser votre activité.

  • A noter qu'il est possible à ce stade de récupérer les données issues d'un précédent lancement qui aurait été interrompu. Suite à cette méthode, onStart() sera lancée.
  • Vient la méthode onStart(). L'activité va devenir visible à l'utilisateur. Ca peut être l'occasion pour vous de charger les données en base de données, mais vous pouvez aussi choisir de le faire dans le onResume()
  • onResume() est lancée lorsque votre application est passée en avant plan, c'est à dire que l'UI est visible, et que l'utilisateur peut intéragir avec elle.
  • Quand une autre activité demande à s'afficher en avant plan, alors votre activité à vous passe dans la méthode onPause(). C'est l'occasion de sauvegarder tout ce qu'il y a à sauvegarder (BDD, Saisies utilisateurs).
Attention toutefois, tant que le traitement de cette méthode n'est pas fini, aucune autres activités ne va pouvoir se lancer, assurez-vous que cette méthode ne prennent pas trop de temps.
  • onStop() est la dernière méthode avant que le système ne décide de libérer définitivement les ressources (CPU et mémoire).
  • Et donc pour finir onDestroy() met fin au cycle de vie de l'activité. Supprime toutes les ressources et certains fichiers temporaires.

Effectuez le tutoriel expliquant le lifecycle sur le codelab de Google

Puisque les événements qui peuvent faire changer l'état de votre application ne sont pas sous votre contrôle, le framework Android expose pour vous des callback vous permettant de réagir suivant les situations du cycle de vie. Notamment sur les activity et les fragment.

Question 11 👉 Quelle est la syntaxe native pour log une information dans la console ?
Question 12 👉 Est-ce qu'un fragment possède un cycle de vie décorrelé d'une activity ou non ? Justifiez
Question 13 👉 Décrivez les étapes par lequelles une application passe lorsqu'elle est coupée par un appel téléphonique entrant.

Vous pouvez ajouter vos actions lorsqu'une étape du cycle de vie de votre application est appelée :

override fun onCreate() {
   super.onCreate()
   Timber.i("onStart Called")
   //Souvent ici que l'on bind l'interface avec le code de l'activity
}
override fun onStart() {
   super.onStart()
   Timber.i("onStart Called")
   //Je peux initialiser certaines valeurs, données, etc.
}
override fun onResume() {
   super.onResume()
   Timber.i("onResume Called")
   //Je peux récuperer un état de l'application pour que l'interface soit à jour
}

override fun onPause() {
   super.onPause()
   Timber.i("onPause Called")
   //Je peux save l'état de mon application par exemple
}

override fun onStop() {
   super.onStop()
   Timber.i("onStop Called")
   //Je peux sauvegarder des données ou lancer un service si besoin
}

override fun onDestroy() {
   super.onDestroy()
   Timber.i("onDestroy Called")
   //Je peux correctement sauvegarder mes données en cas de fermeture brusque
}

override fun onRestart() {
   super.onRestart()
   Timber.i("onRestart Called")
}

Conclusion

Et voilà ! Nous avons fait le tour des notions basiques de la programmation d'application native sur Android.

Vous avez les outils en main pour correctement débuter.

Voici quelques liens de ressources qui vont vous permettre d'aller plus loin et de compléter les exercices qui vont suivre !

Le plus important : Comment s'en sortir sur Android, les ressources et comment s'aider (par Google)

Si vous en êtes ici.

Voici le sujet du TP à réaliser d'ici le prochain cours pour préparer votre projet Space DIM.

🎄 TP Noël - Pour décorer votre sapin
Une petite application sous forme de travail préparatoire au projet qui vous aidera à bien assimiler les concepts de bases Android pour être frais et dispo à la rentrée. 🎄L’applicationLayoutBindingFragmentLifeCycleComme vous le savez à la fin des cours d’Android vous aurez une application à nous pr…