Sobes.tech
Middle

Wie überträgt man richtig große Datenmengen, z.B. ein Bild, zwischen Aktivitäten in Android?

sobes.tech KI

Antwort von AI

Es wird nicht empfohlen, große Datenmengen wie Bilder direkt über Intent zu übertragen, da die Größe der serialisierten Daten (normalerweise einige Hundert Kilobyte oder Megabyte) begrenzt ist. Das Übertragen zu großer Datenmengen kann zu einer TransactionTooLargeException führen.

Korrekte Ansätze:

  1. Daten in eine Datei speichern und den Pfad in Intent übergeben.

    • Das Bild in eine temporäre Datei speichern.
    • Die URI oder den Pfad der Datei im Extra des Intents übergeben.
    • Die empfangende Aktivität liest die Datei anhand des erhaltenen Pfades.
    // In der ersten Aktivität speichern
    val imageUri: Uri = saveImageToFile(bitmap) // Funktion zum Speichern des Bitmaps in eine Datei und Rückgabe der Uri
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtra("image_uri", imageUri.toString())
    startActivity(intent)
    
    // In der zweiten Aktivität lesen
    val imageUriString = intent.getStringExtra("image_uri")
    if (imageUriString != null) {
        val imageUri = Uri.parse(imageUriString)
        val bitmap = loadImageFromFile(imageUri) // Funktion zum Laden des Bitmaps aus der Uri
        imageView.setImageBitmap(bitmap)
    }
    
  2. Singleton oder globaler Datenspeicher verwenden.

    • Daten in einem Singleton-Objekt oder einer separaten Klasse speichern, die überall in der Anwendung zugänglich ist.
    • Es ist nicht notwendig, Daten zwischen Aktivitäten zu übergeben, einfach auf das Singleton zugreifen.
    // Globales Objekt, z.B. in der Application-Klasse oder in einem separaten Singleton
    object DataHolder {
        var bitmap: Bitmap? = null
    }
    
    // In der ersten Aktivität
    DataHolder.bitmap = bitmap
    
    // In der zweiten Aktivität
    val bitmap = DataHolder.bitmap
    imageView.setImageBitmap(bitmap)
    DataHolder.bitmap = null // Nach Verwendung löschen, falls nötig
    

    Dabei ist die Lebenszyklusverwaltung zu beachten, da die Aktivität neu erstellt werden kann.

  3. Datenbank (Room) oder andere Speicherlösungen (z.B. SharedPreferences, aber nicht ideal für Bilder) verwenden.

    • Das Bild (möglicherweise als Byte-Array) in der Datenbank speichern.
    • Die Datenbank-ID per Intent übergeben.
    • Die empfangende Aktivität liest das Bild anhand der Datenbank-ID.
    // Speichern in der ersten Aktivität (Pseudocode für 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)
    
    // Lesen in der zweiten Aktivität (Pseudocode für 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. Shared ViewModel im Navigation Component verwenden.

    • Wenn der Navigation Component verwendet wird, kann ein gemeinsames ViewModel genutzt werden, das an den Navigation-Graph oder die Aktivität gebunden ist.
    • Die Daten werden im ViewModel einer Aktivität gespeichert und sind in einer anderen zugänglich.
    // Im ViewModel
    class SharedViewModel : ViewModel() {
        val imageBitmap = MutableLiveData<Bitmap>()
    }
    
    // In der ersten Aktivität (bei Verwendung des Navigation Component)
    private val sharedViewModel: SharedViewModel by activityViewModels() // oder durch navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.value = bitmap
    
    // In der zweiten Aktivität
    private val sharedViewModel: SharedViewModel by activityViewModels() // oder durch navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap ->
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap)
        }
    }
    

Die Wahl der Methode hängt vom Anwendungsfall, der Datenmenge und der Komplexität der App ab. Für Bilder sind das Speichern in einer Datei (und Übergeben der URI) oder die Verwendung eines Singleton/ViewModel meist die geeignetsten und effizientesten Lösungen.