Comment construire un backend pour une application Android ?
Dans cet article, nous parlerons d’Android, l’un des systèmes d’exploitation les plus populaires. Nous examinerons les avantages et les inconvénients du développement Android, les options de backend pour les applications mobiles et nous vous apprendrons à créer votre propre backend mobile.
Contents
- 1 Principaux enseignements
- 2 Qu’est-ce qu’Android ?
- 3 Avantages du développement Android
- 4 Limites du développement Android
- 5 Options de backend pour les applications Android
- 6 Comment créer un backend pour une application Android ?
- 7 Conclusion
Principaux enseignements
- La domination d’Android: Android, en tant que système d’exploitation à code source ouvert, équipe environ 70 % des appareils mobiles et compte plus de trois milliards d’utilisateurs actifs.
- Options de backend pour les applications: Pour les applications mobiles, les développeurs peuvent opter pour l’infrastructure en tant que service (IaaS), la plateforme en tant que service (PaaS) ou le backend en tant que service (BaaS).
- Etapes pour construire votre backend: Nous fournirons un tutoriel détaillé sur la façon de créer un backend Android en utilisant une plateforme BaaS et le code source à la fin de l’article.
Qu’est-ce qu’Android ?
Android est un système d’exploitation libre et gratuit basé sur Linux. Il a été principalement conçu pour les appareils mobiles tels que les smartphones et les tablettes, mais il est désormais également utilisé pour les téléviseurs intelligents, les systèmes embarqués, les consoles de jeu, etc.
Le développement d’Android a commencé en 2003 par Android Inc. L’entreprise souhaitait initialement créer un système d’exploitation pour les appareils photo numériques, mais elle s’est rapidement orientée vers le développement d’un système d’exploitation mobile afin d’atteindre un marché plus large.
En 2005, la société a été rachetée par Google avec ses employés. La première version d’Android est sortie en 2008.
Bien qu’Android soit un logiciel libre, la plupart des appareils mobiles utilisent la version propriétaire de Google. Cette version est préinstallée avec des logiciels tels que Google Chrome, YouTube, Google TV et Gmail.
En raison des grandes options de personnalisation d’Android, de nombreux fabricants transforment également Android pour mieux représenter leur entreprise. C’est pourquoi OnePlus Android est très différent de Pixel Android.
Android est le système d’exploitation le plus populaire depuis 2013. Il est utilisé par environ 70 % des appareils mobiles et compte plus de trois milliards d’utilisateurs actifs mensuels.
En outre, le Google Play Store vous donne accès à plus de trois millions d’applications mobiles. Poursuivez votre lecture pour apprendre à créer un backend pour une application Android.
Avantages du développement Android
Examinons quelques-uns des avantages du développement pour Android.
Plate-forme croisée
En développant pour Android, vous pouvez cibler une large gamme d’appareils. Cela inclut les téléphones portables, les wearables, les smart TV, les consoles de jeu, etc. Si vous savez coder une application mobile, vous n’aurez aucun mal à développer une application pour wearable ou smart TV.
Un marché énorme
Comme indiqué précédemment, Android détient une part de marché plus importante (70 %) que celle d’iOS (30 %). En développant des applications Android, vous pourrez automatiquement accéder à un public plus large.
De plus, les applications Android sont connues pour leur faible investissement et leur retour sur investissement élevé. Contrairement à iOS, il n’y a pas non plus de frais de développement annuels.
Personnalisation
Les appareils Android sont hautement personnalisables par rapport à d’autres systèmes d’exploitation. Ils vous permettent de modifier pratiquement tout ce que vous pouvez imaginer.
En outre, Android vous permet d’intégrer facilement votre application à d’autres services tiers.
Communauté
Android est soutenu par une vaste communauté de développeurs de logiciels libres. De plus, il est livré avec de nombreux outils conviviaux pour les développeurs, tels qu’Android Studio, ADB et Logcat, qui vous permettent de coder facilement des applications.
Si vous êtes bloqué, il existe plusieurs plateformes où vous pouvez trouver de l’aide, notamment GitHub, StackOverflow, Reddit et d’autres communautés centrées sur Android.
Limites du développement Android
Voici quelques-uns des inconvénients du développement Android.
Sécurité
Android est moins sûr qu’iOS et ne suit pas de protocoles de sécurité stricts. Android étant un logiciel libre, des failles de sécurité sont détectées chaque semaine. Les pirates ont donc la possibilité d’exploiter ces failles avant qu’elles ne soient corrigées.
Les appareils Android peuvent également être rootés pour obtenir un accès de superutilisateur. Bien que cela rende votre appareil plus puissant, c’est également risqué car cela désactive certaines mesures de sécurité intégrées.
Complexité
Les appareils Android sont de formes et de tailles différentes, ce qui est certes une bonne chose, mais peut constituer un inconvénient majeur lorsqu’il s’agit de développer des applications Android pour plusieurs types d’appareils.
Pour que votre application soit compatible avec le plus grand nombre d’appareils possible, vous devrez intégrer la conception réactive, tenir compte du matériel des différents appareils, etc.
Applications Premium
Les applications premium ont moins de succès sur le Google Play Store que sur l’App Store. Ce n’est un secret pour personne que les utilisateurs d’Android ont tendance à dépenser moins pour les applications que les utilisateurs d’iOS. Si vous travaillez sur une application “premium”, considérez Android comme votre deuxième choix.
Options de backend pour les applications Android
Quel est le meilleur backend pour une application Android ? Les backends pour les applications mobiles peuvent être hébergés sur votre propre infrastructure ou déployés sur des services en nuage. Les modèles d’informatique dématérialisée les plus populaires pour les backends mobiles sont les suivants :
- Infrastructure en tant que service (IaaS)
- Plate-forme en tant que service (PaaS)
- Backend en tant que service (BaaS)
Chaque option couvre différentes couches d’abstraction, comme le montre l’image ci-dessous.
Examinons chaque option en détail pour vous aider à choisir le modèle de cloud le plus adapté à vos applications dorsales.
Infrastructure en tant que service (IaaS)
L’infrastructure en tant que service (IaaS) est le modèle d’informatique en nuage le moins abstrait. Dans ce modèle, le fournisseur offre aux utilisateurs des ressources virtualisées, telles que des serveurs, des réseaux, des systèmes de stockage et d’exploitation, par le biais d’API de haut niveau ou de tableaux de bord intuitifs.
L’avantage de l’IaaS est qu’il donne aux utilisateurs un contrôle total sur l’ensemble de leur infrastructure. L’IaaS est le modèle le plus souple et le plus évolutif, mais aussi le plus difficile à gérer. Si vous choisissez cette option, vous aurez probablement besoin d’un ou deux administrateurs système.
Quelques exemples d’IaaS sont Amazon Web Services, Google Cloud Platform et Azure.
Plate-forme en tant que service (PaaS)
La plateforme en tant que service (PaaS) est un modèle d’informatique en nuage conçu pour aider les utilisateurs à développer, gérer et déployer des applications.
Outre la fourniture d’une infrastructure, le PaaS s’accompagne d’outils conviviaux permettant de développer, de personnaliser et de tester des applications.
En utilisant le PaaS, vous pourrez vous concentrer sur votre logiciel et l’expérience utilisateur sans vous soucier de l’infrastructure sous-jacente.
En outre, le PaaS veille à ce que votre application évolue à la demande, s’occupe des sauvegardes, etc. Les inconvénients du PaaS sont un niveau de contrôle plus faible, un risque de verrouillage du fournisseur et des coûts comparativement plus élevés.
Les plateformes PaaS les plus populaires sont Heroku, Render et Digital Ocean App Platform.
Backend en tant que service (BaaS)
Le Backend as a Service (BaaS) automatise la partie backend du développement en fournissant une solution backend complète.
Les fonctionnalités BaaS comprennent la gestion des utilisateurs, les bases de données, l’authentification, les intégrations sociales, les notifications push, les API, les SDK, etc.
Le BaaS offre tous les avantages de l’IaaS et du PaaS tout en proposant des fonctionnalités supplémentaires. Les équipes qui utilisent le BaaS ont tendance à sortir leurs produits plus rapidement, à réduire les coûts d’ingénierie et à créer de meilleurs logiciels.
Les inconvénients du BaaS sont un niveau de contrôle et de personnalisation plus faible et la possibilité d’un verrouillage du fournisseur pour les plateformes non open-source.
Parmi les exemples de BaaS, on peut citer Back4app, AWS Amplify et Firebase.
Comment créer un backend pour une application Android ?
Dans cette section de l’article, nous allons voir comment construire une application backend basée sur Back4app et s’y connecter à partir d’une application Android.
Conditions préalables
- Expérience de Kotlin et du développement Android.
- Compréhension de base du backend mobile en tant que service.
- Java et Android Studio installés sur votre machine locale.
Qu’est-ce que Back4app ?
Back4app est une excellente plateforme pour construire des backends pour des applications modernes et accélérer le processus de développement.
Il est bien équipé avec des fonctionnalités utiles côté serveur telles que la gestion des utilisateurs, les bases de données en temps réel, les intégrations sociales, les fonctions Cloud Code, les notifications push, les API, et bien plus encore !
En utilisant Back4app, vous serez en mesure de délocaliser une grande partie du travail de backend et de vous concentrer sur les aspects critiques de votre application et d’accélérer le développement du backend d’une application Android.
Vous n’aurez pas besoin de vous occuper de l’infrastructure sous-jacente de votre backend, du serveur backend, de la mise à l’échelle, de la maintenance, etc.
Plus important encore, Back4app offre un niveau gratuit qui est idéal pour expérimenter et tester la plateforme. Au fur et à mesure que votre application grandit, vous pouvez passer à un plan premium moyennant un abonnement mensuel.
Introduction du projet
Dans cet article, nous allons créer une simple application de notes. L’application permettra aux utilisateurs d’ajouter, d’éditer et de supprimer des notes. Les notes seront stockées dans la base de données de Back4app et manipulées via Parse SDK.
Nous utiliserons le langage de programmation Kotlin pour construire l’application. Pour l’interface utilisateur, nous utiliserons Jetpack Compose – la boîte à outils moderne d’Android pour construire des interfaces natives.
Créer l’application Back4app
La première étape pour développer un backend pour une application Android est de créer un compte Back4app. Si vous n’en avez pas, inscrivez-vous.
Lorsque vous vous connectez à votre compte Back4app, vous êtes redirigé vers la vue des applications. Cliquez sur “Créer une nouvelle application” pour initialiser le processus de création d’application.
La plateforme Back4app propose deux solutions :
- Backend as a Service (BaaS) – solution backend robuste
- Conteneurs en tant que service (CaaS) – plate-forme de gestion des conteneurs (en particulier des applications web)
Étant donné que nous construisons un backend pour une application mobile, nous opterons pour le “Backend as a Service”.
Donnez à votre application un nom agréable et informatif, sélectionnez “NoSQL” comme base de données et cliquez sur “Créer”. C’est une étape importante pour déployer un backend pour une application Android.
Back4app prendra un peu de temps pour préparer tout ce qui est nécessaire à votre application. Cela inclut la base de données, la gestion des utilisateurs, la mise à l’échelle, les configurations, etc. Une fois que votre application est prête, vous serez redirigé vers la vue de la base de données de votre application.
Conception de la base de données
Passons maintenant à la conception de la base de données. C’est une étape nécessaire pour développer un backend pour une application Android.
Puisque nous construisons une simple application de notes, nous n’aurons besoin que d’une seule classe. Cliquez sur “Créer une classe”, nommez-la Note
, activez “Lecture et écriture publiques”, et cliquez sur “Créer une classe et ajouter des colonnes”.
Ensuite, ajoutez les trois champs suivants à la classe nouvellement créée :
+-------------+-------------+--------------------+----------+
| Data type | Name | Default value | Required |
+-------------+-------------+--------------------+----------+
| String | icon | <leave blank> | yes |
+-------------+-------------+--------------------+----------+
| String | title | <leave blank> | yes |
+-------------+-------------+--------------------+----------+
| String | content | <leave blank> | yes |
+-------------+-------------+--------------------+----------+
Enfin, cliquez sur le bouton “Ajouter une ligne” et alimentez votre base de données avec quelques données d’exemple. Si vous n’avez pas d’idées, vous pouvez également importer ce dumping de données.
Voilà, c’est tout pour le backend.
Code Frontend
Dans cette section de l’article, nous allons démarrer une nouvelle application Android, configurer un ViewModel, implémenter l’interface utilisateur, installer et configurer Parse SDK, et enfin récupérer les données de la base de données en temps réel Back4app.
Projet Init
Comme indiqué dans la section des conditions préalables, les étapes suivantes nécessitent l’installation d’Android Studio. Si vous ne l’avez pas encore, téléchargez-le.
Commencez par ouvrir Android Studio et cliquez sur le bouton “Nouveau projet”.
Sélectionnez ensuite “Activité vide” comme modèle de projet et cliquez sur “Suivant”.
Pour créer votre projet, vous devez fournir un nom et un nom de paquetage. Je vous suggère d’utiliser AndroidApp
comme nom de votre projet et le nom de domaine inversé comme paquetage de votre projet.
Une fois que vous avez tout configuré, cliquez sur “Terminer” pour créer le projet.
Android Studio prendra environ deux minutes pour préparer tout ce qui est nécessaire. Cela inclut la création de la structure du fichier du projet, la configuration de Gradle, l’installation des dépendances, etc.
Une fois que votre projet est prêt, utilisez l’explorateur pour naviguer jusqu’à MainActivity.kt et remplacez son contenu :
// app/src/main/java.<your_package_name>/MainActivity.kt
package <your.package.name>
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
) {
Text(text = "Back4app rocks!", fontSize = 18.sp)
}
}
}
}
}
Veillez à toujours remplacer par le nom de votre paquet.
Enfin, essayez de lancer l’application en cliquant sur le bouton vert de lecture ou sur les touches Shift + F10
de votre clavier. Si tout se passe bien, l’émulateur devrait démarrer et vous devriez voir le message Back4app rocks
à l’écran.
Modèle de vue
Pour gérer l’état global de notre application, nous utiliserons un ViewModel.
Mais avant cela, nous devons créer une classe de données Note
avec les mêmes attributs que celle de notre base de données Back4app.
Créez une classe de données nommée Note :
// app/src/main/java.<your_package_name>/Note.kt
package <your.package.name>
data class Note(
var objectId: String? = null,
var icon: String,
var title: String,
var content: String,
) {
companion object {
fun generateObjectId(): String {
val chars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
return (1..10).map { chars.random() }.joinToString("")
}
}
}
- Nous avons défini la méthode statique
generateObjectId()
pour générer des identifiants d’objets de type Parse. objectId
est nullable puisque nous supposerons plus tard que siobjectId == null
, l’objet n’a pas encore été sauvegardé dans la base de données.
Ensuite, créez une classe AppViewModel
avec le contenu suivant :
// app/src/main/java.<your_package_name>/AppViewModel.kt
package <your.package.name>
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
class AppViewModel : ViewModel() {
val notes: MutableState<Map<String, Note>> = mutableStateOf(mapOf(
"7IggsqFAKt" to Note(
objectId = "7IggsqFAKt",
icon = "\uD83D\uDE80",
title = "Deploy app",
content = "Go ahead and deploy your backend to Back4app.",
),
"eFRNm0hTat" to Note(
objectId = "eFRNm0hTat",
icon = "\uD83C\uDFA8",
title = "Design website",
content = "Design the website for the conference.",
),
"uC7hTQmG5F" to Note(
objectId = "uC7hTQmG5F",
icon = "\uD83D\uDC42",
title = "Attend meeting",
content = "Attend meeting with the team to discuss the conference.",
),
))
companion object {
@Volatile
private var instance: AppViewModel? = null
fun getInstance(): AppViewModel {
return instance ?: synchronized(this) {
instance ?: AppViewModel().also { instance = it }
}
}
}
}
- Nous avons utilisé l’
état mutable de
Compose pour déclencher des mises à jour de l’interface utilisateur en cas de modification des données. - Le
MutableState
contient unecarte d'
identifiants d'objets
et denotes
, que nous avons remplie avec des données. - Pour s’assurer qu’il n’y a qu’une seule instance d’
AppViewModel
, nous avons utilisé le modèle singleton.
Nous pouvons maintenant accéder à l’instance AppViewModel
dans nos activités via AppViewModel.getInstance().
Activité principale
Remplacez le contenu de MainActivity.kt par le code suivant pour afficher les notes :
// app/src/main/java.<your_package_name>/MainActivity.kt
package <your.package.name>
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
class MainActivity : ComponentActivity() {
private val viewModel = AppViewModel.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val context = this as Context
setContent {
MainActivityContent(
viewModel = viewModel,
onNoteListItemClick = {
// TODO: Open note edit form
},
onNoteAddClick = {
// TODO: Open note create form
},
)
}
}
}
@Composable
fun MainActivityContent(
viewModel: AppViewModel,
onNoteListItemClick: (note: Note) -> Unit,
onNoteAddClick: () -> Unit,
) {
val notes = viewModel.notes.value
MaterialTheme {
Scaffold(
topBar = { TopAppBar(title = { Text("My Notes") }) },
floatingActionButton = {
ExtendedFloatingActionButton(
onClick = { onNoteAddClick() },
icon = { Icon(Icons.Filled.Add, contentDescription = "Add") },
text = { Text("Add") }
)
},
) { contentPadding ->
Box(modifier = Modifier.padding(contentPadding)) {
NoteList(notes, onNoteListItemClick = { onNoteListItemClick(it) })
}
}
}
}
@Composable
fun NoteListItem(note: Note, onNoteListItemClick: (note: Note) -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = { onNoteListItemClick(note) })
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = note.icon, fontSize = 32.sp, modifier = Modifier.size(48.dp))
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(text = note.title, fontSize = 18.sp)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = note.content,
fontSize = 14.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
}
@Composable
fun NoteList(notes: Map<String, Note>, onNoteListItemClick: (note: Note) -> Unit) {
LazyColumn {
items(notes.entries.toList()) { (_, note) ->
NoteListItem(note = note, onNoteListItemClick = onNoteListItemClick)
}
}
}
- Les
notes
sont maintenant extraites dumodèle AppViewModel.
- Au lieu de définir les événements de clic dans les composables, nous les avons transmis en tant qu’arguments.
- Nous avons utilisé Compose pour concevoir l’interface utilisateur. Pour la rendre plus fluide, nous avons incorporé
MaterialTheme
à la mise en page deScaffold
.
Si vous reconstruisez l’application maintenant, vous devriez voir la liste des notes “codées en dur” à l’écran.
Formulaire de note Activité
Dans cette section, nous allons ajouter une nouvelle activité qui permettra aux utilisateurs d’ajouter et de modifier des notes.
Commencez par créer une nouvelle classe nommée FormActivity
avec le contenu suivant :
// app/src/main/java.<your_package_name>/FormActivity.kt
package <your.package.name>
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Button
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
class FormActivity : ComponentActivity() {
private val viewModel = AppViewModel.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val objectId = intent.getStringExtra("objectId")
val note = if (objectId !== null) viewModel.notes.value[objectId] else null
setContent {
FormActivityContent(
note,
onNoteAddClick = { icon: String, title: String, content: String ->
if (note !== null) return@FormActivityContent
val newNote = Note(
icon = icon,
title = title,
content = content,
)
newNote.objectId = Note.generateObjectId()
viewModel.notes.value += (newNote.objectId!! to newNote)
finish()
},
onNoteSaveClick = { icon: String, title: String, content: String ->
if (note === null) return@FormActivityContent
val updatedNote = note.copy()
updatedNote.icon = icon
updatedNote.title = title
updatedNote.content = content
viewModel.notes.value += (updatedNote.objectId!! to updatedNote)
finish()
},
onNoteDeleteClick = {
if (note === null) return@FormActivityContent
viewModel.notes.value = viewModel.notes.value.filter {
it.value.objectId != note.objectId
}
finish()
},
)
}
}
}
@Composable
fun FormActivityContent(
note: Note?,
onNoteAddClick: (icon: String, title: String, content: String) -> Unit,
onNoteSaveClick: (icon: String, title: String, content: String) -> Unit,
onNoteDeleteClick: () -> Unit,
) {
MaterialTheme {
Scaffold(
topBar = {
TopAppBar(title = { Text(note?.let { "Edit Note" } ?: ("Add Note")) })
},
floatingActionButton = {
if (note !== null) {
ExtendedFloatingActionButton(
onClick = { onNoteDeleteClick() },
icon = { Icon(Icons.Filled.Delete, "Delete") },
text = { Text("Delete") },
)
}
},
) { contentPadding ->
Box(modifier = Modifier.padding(contentPadding)) {
NoteForm(note = note, onNoteSave = { icon, title, content ->
if (note === null) {
onNoteAddClick(icon, title, content)
} else {
onNoteSaveClick(icon, title, content)
}
})
}
}
}
}
@Composable
fun NoteForm(
note: Note?,
onNoteSave: (icon: String, title: String, content: String) -> Unit
) {
var icon by remember { mutableStateOf(TextFieldValue(note?.icon ?: "")) }
var title by remember { mutableStateOf(TextFieldValue(note?.title ?: "")) }
var content by remember { mutableStateOf(TextFieldValue(note?.content ?: "")) }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
TextField(
label = { Text(text = "Icon") },
value = icon,
onValueChange = { icon = it },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
label = { Text(text = "Title") },
value = title,
onValueChange = { title = it },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
label = { Text(text = "Content") },
value = content,
onValueChange = { content = it },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = { onNoteSave(icon.text, title.text, content.text) },
Modifier.fillMaxWidth()
) {
Text(text = "Save")
}
}
}
- Ce formulaire est utilisé pour ajouter et modifier des notes. Pour déterminer l’action, nous comparons
objectId == null
. Dans le cas denull
, il s’agit d’une action d’ajout, sinon d’une action d’édition. - Si
objectId !== null
, nous récupérons lanote
dans l’état et remplissons le formulaire. - Pour que
MutableState
fonctionne correctement, nous devions considérer son contenu comme immuable. C’est pourquoi nous avons parfois copié le contenu au lieu de le modifier. - Nous avons géré l’état du formulaire Compose via
mutableStateOf().
Ensuite, enregistrez la FormActivity
au bas de l’application
dans AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<!-- ... -->
<activity android:name=".FormActivity"/>
</application>
</manifest>
Enfin, créez un nouvel Intent
sur onNoteListItemClick
et onNoteAddClick
dans MainActivity.kt:
// app/src/main/java.<your_package_name>/MainActivity.kt
class MainActivity : ComponentActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
// ...
setContent {
MainActivityContent(
viewModel = viewModel,
onNoteListItemClick = {
// triggers the edit action, since `objectId` is provided
val intent = Intent(context, FormActivity::class.java)
intent.putExtra("objectId", it.objectId)
context.startActivity(intent)
},
onNoteAddClick = {
// triggers the add action, since no `objectId` is present
val intent = Intent(context, FormActivity::class.java)
context.startActivity(intent)
},
)
}
}
}
N’oubliez pas d’importer l’intention
en haut du fichier :
import android.content.Intent
Si vous reconstruisez l’application, vous remarquerez que nous avons maintenant une application fonctionnelle. L’application nous permet d’ajouter des notes, de les modifier et de les supprimer.
Le seul problème est que le redémarrage de l’application réinitialise son état (aux notes “codées en dur”).
Dans la section suivante, nous allons connecter l’application au backend Back4app. Cela nous permettra de conserver l’état et de le synchroniser entre plusieurs appareils.
Installer le SDK Parse
Comme vous le savez peut-être, Back4app est basé sur la plateforme Parse. Si nous voulons interagir avec la base de données de Back4app ou Back4app en général, nous devons installer le SDK Parse.
Commencez par ajouter le dépôt JitPack à settings.gradle :
// settings.gradle
pluginManagement {
repositories {
// ...
maven { url "https://jitpack.io" }
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
// ...
maven { url "https://jitpack.io" }
}
}
Ensuite, ajoutez le SDK Android Parse au build.gradle de l’application :
// app/build.gradle
dependencies {
// ...
implementation "com.github.parse-community.Parse-SDK-Android:parse:4.2.0"
}
Synchroniser les paramètres Gradle et s’assurer qu’il n’y a pas d’erreurs.
Configurer Parse SDK
Pour vous connecter au backend de Back4app, vous devrez fournir à Parse SDK votre identifiant d’application et votre clé client. Pour obtenir ces informations, naviguez dans votre application Back4app et sélectionnez “App Settings > Security & Keys” dans la barre latérale.
Ajoutez-les ensuite à votre strings.xml comme suit :
<!-- app/src/main/res/values/strings.xml -->
<resources>
<string name="app_name">back4app-android-app</string>
<string name="back4app_server_url">https://parseapi.back4app.com/</string>
<string name="back4app_app_id">your_parse_app_id</string>
<string name="back4app_client_key">your_parse_client_key</string>
</resources>
Veillez à remplacer
your_parse_app_id
etyour_parse_client_key
par vos identifiants.
Ensuite, modifiez votre AndroidManifest.xml pour activer l’accès à Internet et joindre les métadonnées d’identification :
<!-- app/src/main/AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- these two permissions enable internet access -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application>
<!-- ... -->
<!-- newly added metadata -->
<meta-data
android:name="com.parse.SERVER_URL"
android:value="@string/back4app_server_url" />
<meta-data
android:name="com.parse.APPLICATION_ID"
android:value="@string/back4app_app_id" />
<meta-data
android:name="com.parse.CLIENT_KEY"
android:value="@string/back4app_client_key" />
</application>
</manifest>
La dernière chose à faire est d’initialiser Parse. Pour s’assurer que Parse est initialisé avant toute activité, nous allons créer une nouvelle classe nommée App
, qui hérite de la classe Application
.
Créez App.kt et initialisez Parse comme suit :
// app/src/main/java/<your_package_name>/App.kt
package <your.package.name>
import android.app.Application
import com.parse.Parse
class App : Application() {
override fun onCreate() {
super.onCreate()
Parse.initialize(
Parse.Configuration.Builder(this)
.applicationId(getString(R.string.back4app_app_id))
.clientKey(getString(R.string.back4app_client_key))
.server(getString(R.string.back4app_server_url))
.build()
)
}
}
Enregistrez ensuite la classe App
dans AndroidManifest.xml :
<!-- app/src/main/AndroidManifest.xml -->
<application
android:name=".App"
...
>
<!-- ... -->
</application>
Reconstruisez l’application une fois de plus et vérifiez dans la fenêtre Logcat s’il y a des erreurs. S’il n’y a pas d’erreurs, la connexion à Back4app a réussi.
Charger les notes de Back4app
La dernière chose qu’il nous reste à faire avant de terminer notre application est de charger les notes de la base de données de Back4app et de voir comment utiliser Parse en pratique.
Commencez par naviguer vers le modèle AppViewModel
. Supprimez les données de la carte et ajoutez le bloc init
:
// app/src/main/java/<your_package_name>/AppViewModel.kt
package <your.package.name>
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
class AppViewModel : ViewModel() {
val notes: MutableState<Map<String, Note>> = mutableStateOf(mapOf())
init {
val query = com.parse.ParseQuery.getQuery<com.parse.ParseObject>("Note")
query.orderByDescending("createdAt")
query.findInBackground { notes, e ->
if (e == null) {
for (parseNote in notes) {
val note = Note(
objectId = parseNote.objectId,
icon = parseNote.getString("icon")!!,
title = parseNote.getString("title")!!,
content = parseNote.getString("content")!!,
)
this.notes.value += (note.objectId!! to note)
}
} else {
println("Error: ${e.message}")
}
}
}
companion object {
// ...
}
}
Ce code utilise Parse SDK pour récupérer les notes dans les bases de données, les transformer en classe de données Note
et les enregistrer dans la carte.
Ensuite, ajoutez les trois méthodes suivantes à Note :
// app/src/main/java/<your_package_name>/Note.kt
package <your.package.name>
import com.parse.ParseObject
import com.parse.ParseQuery
data class Note(
var objectId: String? = null,
var icon: String,
var title: String,
var content: String,
) {
fun addToParse(callback: (objectId: String) -> Unit) {
if (objectId !== null) throw Exception("Note is already saved to Parse!")
val parseNote = ParseObject("Note")
parseNote.put("icon", icon)
parseNote.put("title", title)
parseNote.put("content", content)
parseNote.saveInBackground {
if (it !== null) throw Exception("Error: ${it.message}")
objectId = parseNote.objectId
callback(parseNote.objectId)
}
}
fun updateToParse(callback: (objectId: String) -> Unit) {
if (objectId === null) throw Exception("Note hasn't been saved to Parse yet!")
val query = ParseQuery.getQuery<ParseObject>("Note")
val parseNote = query.get(objectId)
parseNote.put("icon", icon)
parseNote.put("title", title)
parseNote.put("content", content)
parseNote.saveInBackground {
if (it !== null) throw Exception("Error: ${it.message}")
callback(parseNote.objectId)
}
}
fun deleteFromParse(callback: () -> Unit) {
if (objectId === null) throw Exception("Note hasn't been saved to Parse yet!")
val query = ParseQuery.getQuery<ParseObject>("Note")
val parseNote = query.get(objectId)
parseNote.deleteInBackground {
if (it !== null) throw Exception("Error: ${it.message}")
callback()
}
}
}
addToParse()
ajoute une nouvelle note au serveur Parse avec ses détails. En cas de succès, elle stocke l’identifiant unique de la note et notifie la fin de l’opération.updateToParse()
met à jour les informations d’une note existante sur le serveur Parse. En cas de succès, elle signale qu’elle a terminé après avoir effectué les modifications.deleteFromParse()
supprime une note sauvegardée sur le serveur Parse. En cas de succès, elle confirme la suppression lorsqu’elle est terminée.
Enfin, modifiez les méthodes de clic dans FormActivity
pour invoquer les méthodes nouvellement définies :
// app/src/main/java/<your_package_name>/NoteFormActivity.kt
class FormActivity : ComponentActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
// ...
setContent {
FormActivityContent(
note,
onNoteAddClick = { icon: String, title: String, content: String ->
if (note !== null) return@FormActivityContent
val newNote = Note(
icon = icon,
title = title,
content = content,
)
newNote.addToParse {
viewModel.notes.value += (it to newNote)
finish()
}
},
onNoteSaveClick = { icon: String, title: String, content: String ->
if (note === null) return@FormActivityContent
val updatedNote = note.copy()
updatedNote.icon = icon
updatedNote.title = title
updatedNote.content = content
updatedNote.updateToParse {
viewModel.notes.value += (it to updatedNote)
finish()
}
},
onNoteDeleteClick = {
if (note === null) return@FormActivityContent
viewModel.notes.value = viewModel.notes.value.filter {
it.value.objectId != note.objectId
}
note.deleteFromParse {
finish()
}
},
)
}
}
}
C’est tout !
L’application est maintenant complètement fonctionnelle et synchronisée avec le backend de Back4app. Essayez de jouer avec l’application en changeant les données et en vérifiant si les changements sont reflétés dans la vue de la base de données.
Conclusion
Dans cet article, nous avons réussi à construire un backend mobile et à nous y connecter depuis notre application Android. Nous avons utilisé la solution BaaS de Back4app pour le backend, et sur le frontend, nous avons utilisé Kotlin avec Jetpack Compose.
Vous devriez maintenant avoir une bonne compréhension du fonctionnement des backends mobiles et être en mesure de construire le vôtre. Voir le code source final sur le repo back4app-android-app.