Sobes.tech
Middle

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:

  1. 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 Extra van 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)
    }
    
  2. 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 nodig
    

    Houd rekening met de levenscyclus van de app en de activiteit die mogelijk wordt hergecreëerd.

  3. 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)
        }
    }
    
  4. Gebruik een gedeelde ViewModel in Navigation Component.

    • Als je Navigation Component gebruikt, kun je een gedeelde ViewModel gebruiken die gekoppeld is aan de navigatiegrafiek of activiteit.
    • De gegevens worden in de ViewModel van éé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)
        }
    }
    

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.