🍦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.
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
Les concepts de base
Getting started
- Commencez par télécharger Android Studio à cette adresse : https://developer.android.com/studio
- Suivez le tutoriel Google suivant : https://codelabs.developers.google.com/codelabs/kotlin-android-training-get-started/#0
- Faites valider votre Hello world et les réponses aux questions suivantes par l'enseignant.
- 🗂 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
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

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é.



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.

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 deuxactivity
dans son app. On préfèrera avoir beaucoup defragment
plus maléables et réutilisables.
Expérimentez en réalisant les tutoriels suivants sur codelabs :
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 ? ⬇️️️ ⬇️️️ ⬇️️️

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 leonResume()
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).
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
.
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.
Le plus important : Comment s'en sortir sur Android, les ressources et comment s'aider (par Google)
- Google Fundamentals for Android
- Glossaire collaboratif sur HackMD à compléter par vous tous
- Google Advanced notions for Android
- Android Arsenal (Des bibliothèques à gogo)
Si vous en êtes ici.
Voici le sujet du TP à réaliser d'ici le prochain cours pour préparer votre projet Space DIM.
