Comment transmettre correctement une grande quantité de données, comme une image, entre les activités dans Android?
sobes.tech IA
Réponse de l'IA
Il n’est pas recommandé de transférer directement de grandes volumes de données, comme des images, via Intent en raison de la limite de taille des données sérialisées (généralement quelques centaines de kilo-octets ou mégaoctets). Le transfert de données trop volumineuses peut entraîner une TransactionTooLargeException.
Approches correctes :
-
Enregistrer les données dans un fichier et transmettre le chemin du fichier dans
Intent.- Enregistrer l’image dans un fichier temporaire.
- Transmettre l’URI ou le chemin du fichier dans l’
Extrade l’intent. - L’activité réceptrice lit le fichier à partir du chemin reçu.
// Enregistrer dans la première activité val imageUri: Uri = saveImageToFile(bitmap) // Fonction pour sauvegarder le Bitmap dans un fichier et retourner l’Uri val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_uri", imageUri.toString()) startActivity(intent) // Lire dans la deuxième activité val imageUriString = intent.getStringExtra("image_uri") if (imageUriString != null) { val imageUri = Uri.parse(imageUriString) val bitmap = loadImageFromFile(imageUri) // Fonction pour charger le Bitmap depuis l’Uri imageView.setImageBitmap(bitmap) } -
Utiliser un Singleton ou un stockage global de données.
- Placer les données dans un objet Singleton ou dans une classe séparée accessible depuis n’importe quelle partie de l’application.
- Il n’est pas nécessaire de passer quoi que ce soit entre les activités, il suffit d’accéder au Singleton pour obtenir les données.
// Objet global, par exemple dans la classe Application ou dans un singleton séparé object DataHolder { var bitmap: Bitmap? = null } // Dans la première activité DataHolder.bitmap = bitmap // Dans la deuxième activité val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Nettoyage après utilisation, si nécessaireIl faut prendre en compte le cycle de vie de l’application et de l’activité, qui peut être recréée.
-
Utiliser une base de données (Room) ou un stockage de données (par exemple, SharedPreferences, bien que ce ne soit pas idéal pour les images).
- Enregistrer l’image (peut-être sous forme de tableau d’octets) dans la base de données.
- Transmettre l’identifiant de l’enregistrement dans la base de données via
Intent. - L’activité réceptrice lit l’image depuis la base de données en utilisant l’identifiant.
// Enregistrement dans la première activité (pseudocode pour Room) val imageEntity = ImageEntity(imageData = bitmapToByteArray(bitmap)) val imageId = imageDatabase.imageDao().insertImage(imageEntity) val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_id", imageId) startActivity(intent) // Lecture dans la deuxième activité (pseudocode pour Room) val imageId = intent.getLongExtra("image_id", -1) if (imageId != -1L) { val imageEntity = imageDatabase.imageDao().getImageById(imageId) if (imageEntity != null) { val bitmap = byteArrayToBitmap(imageEntity.imageData) imageView.setImageBitmap(bitmap) } } -
Utiliser un ViewModel partagé dans le composant de navigation.
- Si le composant de navigation est utilisé, on peut utiliser un
ViewModelcommun lié au graphe de navigation ou à l’activité. - Les données sont placées dans le
ViewModeld’une activité et accessibles dans une autre.
// Dans le ViewModel class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // Dans la première activité (avec Navigation Component) private val sharedViewModel: SharedViewModel by activityViewModels() // ou par navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.value = bitmap // Dans la deuxième activité private val sharedViewModel: SharedViewModel by activityViewModels() // ou par navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap -> if (bitmap != null) { imageView.setImageBitmap(bitmap) } } - Si le composant de navigation est utilisé, on peut utiliser un
Le choix de la méthode dépend du scénario d’utilisation, de la taille des données et de la complexité de l’application. Pour les images, l’enregistrement dans un fichier (et la transmission de l’URI) ou l’utilisation d’un Singleton/ViewModel sont généralement les solutions les plus appropriées et efficaces.