Hoe stuur je correct een grote hoeveelheid gegevens, zoals een afbeelding, tussen activiteiten in Android?
sobes.tech AI
Antwoord van AI
Het doorgeven van grote hoeveelheden gegevens, zoals een afbeelding, rechtstreeks via Intent wordt niet aanbevolen vanwege de beperking op de grootte van gegevens die tijdens serialisatie worden doorgegeven (meestal enkele honderden kilobytes of megabytes). Het doorgeven van te grote gegevens kan leiden tot een TransactionTooLargeException.
Juiste benaderingen:
-
Sla de gegevens op in een bestand en geef het pad naar het bestand door in de
Intent.- Sla de afbeelding op in een tijdelijk bestand.
- Geef de URI of het pad naar het bestand door in de
Extravan de intent. - De ontvangende activiteit leest het bestand op het ontvangen pad.
// Opslaan in de eerste activiteit val imageUri: Uri = saveImageToFile(bitmap) // Functie om Bitmap op te slaan in een bestand en Uri terug te geven val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_uri", imageUri.toString()) startActivity(intent) // Lezen in de tweede activiteit val imageUriString = intent.getStringExtra("image_uri") if (imageUriString != null) { val imageUri = Uri.parse(imageUriString) val bitmap = loadImageFromFile(imageUri) // Functie om Bitmap te laden uit Uri imageView.setImageBitmap(bitmap) } -
Gebruik een Singleton of globale gegevensopslag.
- Plaats de gegevens in een Singleton-object of een aparte klasse die vanuit elke plek in de app toegankelijk is.
- Er is geen noodzaak om gegevens tussen activiteiten door te geven, je kunt gewoon de Singleton raadplegen.
// Globaal object, bijvoorbeeld in de Application-klasse of een aparte singleton object DataHolder { var bitmap: Bitmap? = null } // In de eerste activiteit DataHolder.bitmap = bitmap // In de tweede activiteit val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Opruimen na gebruik, indien nodigHoud rekening met de levenscyclus van de app en de activiteit die mogelijk wordt hergecreëerd.
-
Gebruik een database (Room) of gegevensopslag (bijvoorbeeld SharedPreferences, hoewel niet ideaal voor afbeeldingen).
- Sla de afbeelding op (mogelijk als byte-array) in de database.
- Geef de record-ID door in de database via
Intent. - De ontvangende activiteit leest de afbeelding uit de database op basis van de ID.
// Opslaan in de eerste activiteit (pseudo-code voor 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) // Lezen in de tweede activiteit (pseudo-code voor 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) } } -
Gebruik een gedeelde ViewModel in Navigation Component.
- Als je Navigation Component gebruikt, kun je een gedeelde
ViewModelgebruiken die gekoppeld is aan de navigatiegrafiek of activiteit. - De gegevens worden in de
ViewModelvan één activiteit geplaatst en zijn beschikbaar voor de andere.
// In de ViewModel class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // In de eerste activiteit (bij gebruik van Navigation Component) private val sharedViewModel: SharedViewModel by activityViewModels() // of door navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.value = bitmap // In de tweede activiteit private val sharedViewModel: SharedViewModel by activityViewModels() // of door navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap -> if (bitmap != null) { imageView.setImageBitmap(bitmap) } } - Als je Navigation Component gebruikt, kun je een gedeelde
De keuze van methode hangt af van het gebruiksscenario, de grootte van de gegevens en de complexiteit van de app. Voor afbeeldingen zijn het opslaan in een bestand (en het doorgeven van de URI) of het gebruik van Singleton/ViewModel meestal de meest geschikte en efficiënte oplossingen.