Sobes.tech
Middle

Jak správně přenést velké množství dat, například obrázek, mezi aktivitami v Androidu?

sobes.tech AI

Odpověď od AI

Předat velkého objemu dat, jako je obrázek, přímo přes Intent se nedoporučuje kvůli omezení velikosti dat přenášených při serializaci (obvykle několik stovek kilobajtů nebo megabajtů). Přenos příliš velkých dat může vést k TransactionTooLargeException.

Správné přístupy:

  1. Uložit data do souboru a předat cestu k souboru v Intent.

    • Uložíme obrázek do dočasného souboru.
    • Předáme URI nebo cestu k souboru v Extra intentu.
    • Přijímající aktivita načte soubor podle obdržené cesty.
    // Uložení v první aktivitě
    val imageUri: Uri = saveImageToFile(bitmap) // Funkce pro uložení Bitmap do souboru a vrácení Uri
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtra("image_uri", imageUri.toString())
    startActivity(intent)
    
    // Čtení ve druhé aktivitě
    val imageUriString = intent.getStringExtra("image_uri")
    if (imageUriString != null) {
        val imageUri = Uri.parse(imageUriString)
        val bitmap = loadImageFromFile(imageUri) // Funkce pro načtení Bitmap z Uri
        imageView.setImageBitmap(bitmap)
    }
    
  2. Použít Singleton nebo globální úložiště dat.

    • Umístíme data do Singleton objektu nebo do samostatné třídy, která je dostupná z libovolného místa v aplikaci.
    • Není třeba předávat data mezi aktivitami, stačí odkazovat na Singleton pro získání dat.
    // Globální objekt, například v třídě Application nebo v samostatném singletonu
    object DataHolder {
        var bitmap: Bitmap? = null
    }
    
    // V první aktivitě
    DataHolder.bitmap = bitmap
    
    // Ve druhé aktivitě
    val bitmap = DataHolder.bitmap
    imageView.setImageBitmap(bitmap)
    DataHolder.bitmap = null // Vyčištění po použití, pokud je potřeba
    

    Je třeba vzít v úvahu životní cyklus aplikace a aktivitu, která může být znovu vytvořena.

  3. Použít databázi (Room) nebo úložiště dat (například SharedPreferences, i když pro obrázky není ideální).

    • Uložit obrázek (možná ve formě byte pole) do databáze.
    • Přenést identifikátor záznamu v databázi přes Intent.
    • Přijímající aktivita načte obrázek z databáze podle ID.
    // Uložení v první aktivitě (pseudo-kód pro 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)
    
    // Čtení ve druhé aktivitě (pseudo-kód pro 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. Použít sdílený ViewModel v Navigation Component.

    • Pokud používáte Navigation Component, můžete použít sdílený ViewModel, který je spojen s navigačním grafem nebo aktivitou.
    • Data jsou umístěna v ViewModel jedné aktivity a jsou dostupná jiné.
    // Ve ViewModel
    class SharedViewModel : ViewModel() {
        val imageBitmap = MutableLiveData<Bitmap>()
    }
    
    // V první aktivitě (při použití Navigation Component)
    private val sharedViewModel: SharedViewModel by activityViewModels() // nebo by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.value = bitmap
    
    // Ve druhé aktivitě
    private val sharedViewModel: SharedViewModel by activityViewModels() // nebo by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap ->
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap)
        }
    }
    

Volba metody závisí na scénáři použití, velikosti dat a složitosti aplikace. U obrázků je často nejefektivnější uložit je do souboru (a předat URI) nebo použít Singleton/ViewModel, což jsou nejčastěji vhodná a efektivní řešení.