Sobes.tech
Middle

Hogyan lehet helyesen átadni nagy mennyiségű adatot, például egy képet, az Androidban az aktivitások között?

sobes.tech MI

Válasz az MI-től

Nagy mennyiségű adat, például kép közvetlen átadása az Intent segítségével nem ajánlott, mivel a serializálás során átadott adatmennyiség korlátozott (általában néhány száz kilobyte vagy megabájt). Túl nagy adatok átadása TransactionTooLargeException-hez vezethet.

Helyes megközelítések:

  1. Adatok mentése fájlba és az útvonal átadása az Intent-tel.

    • A képet ideiglenes fájlba mentjük.
    • Az URI-t vagy az útvonalat az Extra-ban adjuk át.
    • A fogadó aktivitás olvassa a fájlt a kapott útról.
    // Mentés az első aktivitásban
    val imageUri: Uri = saveImageToFile(bitmap) // Függvény a Bitmap fájlba mentésére és Uri visszaadására
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtra("image_uri", imageUri.toString())
    startActivity(intent)
    
    // Olvasás a második aktivitásban
    val imageUriString = intent.getStringExtra("image_uri")
    if (imageUriString != null) {
        val imageUri = Uri.parse(imageUriString)
        val bitmap = loadImageFromFile(imageUri) // Függvény a Bitmap betöltésére Uri-ból
        imageView.setImageBitmap(bitmap)
    }
    
  2. Singleton vagy globális adat tárolás használata.

    • Az adatokat egy Singleton objektumba vagy külön osztályba helyezzük, amely mindenhol elérhető.
    • Nincs szükség az adatok átadására aktivitások között, csak a Singleton-t kérjük le.
    // Globális objektum, például az Application osztályban vagy külön singletonben
    object DataHolder {
        var bitmap: Bitmap? = null
    }
    
    // Az első aktivitásban
    DataHolder.bitmap = bitmap
    
    // A második aktivitásban
    val bitmap = DataHolder.bitmap
    imageView.setImageBitmap(bitmap)
    DataHolder.bitmap = null // Tisztítás használat után, ha szükséges
    

    Figyelembe kell venni az alkalmazás életciklusát és az aktivitás újraalkotását.

  3. Adatbázis (Room) vagy adat tárolás használata (például SharedPreferences, bár nem ideális képekhez).

    • A képet (esetleg byte-array-ként) elmentjük az adatbázisba.
    • Az adatbázis rekord azonosítóját átadjuk az Intent-tel.
    • A fogadó aktivitás azonosító alapján olvassa a képet az adatbázisból.
    // Mentés az első aktivitásban (pseudo-kód Room-hoz)
    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)
    
    // Olvasás a második aktivitásban (pseudo-kód Room-hoz)
    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 használata a Navigation Component-ben.

    • Ha a Navigation Component-et használod, akkor egy közös ViewModel-t lehet alkalmazni, amely a navigációs gráfhoz vagy az aktivitáshoz kapcsolódik.
    • Az adatok az egyik aktivitásban kerülnek a ViewModel-be, és elérhetőek a másik számára.
    // A ViewModel-ben
    class SharedViewModel : ViewModel() {
        val imageBitmap = MutableLiveData<Bitmap>()
    }
    
    // Az első aktivitásban (Navigation Component esetén)
    private val sharedViewModel: SharedViewModel by activityViewModels() // vagy by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.value = bitmap
    
    // A második aktivitásban
    private val sharedViewModel: SharedViewModel by activityViewModels() // vagy by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap ->
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap)
        }
    }
    

A módszer kiválasztása a használati forgatókönyvtől, az adatok méretétől és az alkalmazás összetettségétől függ. Képek esetén a fájlba mentés (és URI átadása) vagy Singleton/ViewModel használata a leggyakoribb és leghatékonyabb megoldás.