Sobes.tech
Middle

Kuidas õigesti edastada suur andmemaht, näiteks pilt, Androidi tegevuste vahel?

sobes.tech AI

Vastus AI-lt

Suure mahu andmete, näiteks pildi, otse Intent kaudu edastamine ei ole soovitatav, kuna serialiseerimise ajal edastatavate andmete suurusel on piirang (tavaliselt mõnesaja kilobaiti või megabaiti). Liiga suurte andmete edastamine võib põhjustada TransactionTooLargeException.

Õige lähenemine:

  1. Salvesta andmed faili ja edasta faili tee Intent kaudu:

    • Salvesta pilt ajutisse faili.
    • Edasta URI või faili tee Extra kaudu.
    • Vastuvõttev aktiivsus loeb faili vastavalt saadud teele.
    // Esimeses aktiivsuses salvestamine
    val imageUri: Uri = saveImageToFile(bitmap) // Funktsioon, mis salvestab Bitmap faili ja tagastab URI
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtra("image_uri", imageUri.toString())
    startActivity(intent)
    
    // Teises aktiivsuses lugemine
    val imageUriString = intent.getStringExtra("image_uri")
    if (imageUriString != null) {
        val imageUri = Uri.parse(imageUriString)
        val bitmap = loadImageFromFile(imageUri) // Funktsioon, mis laadib Bitmap URI-st
        imageView.setImageBitmap(bitmap)
    }
    
  2. Kasuta Singleton või globaalset andmete hoidlat:

    • Hoia andmeid Singleton-objekti või eraldi klassis, mis on kättesaadav igast rakenduse osast.
    • Aktiivsuste vahel midagi edastada ei ole vaja, lihtsalt pöördu Singleton-i poole andmete saamiseks.
    // Globaalne objekt, näiteks Application klassis või eraldi singleton
    object DataHolder {
        var bitmap: Bitmap? = null
    }
    
    // Esimeses aktiivsuses
    DataHolder.bitmap = bitmap
    
    // Teises aktiivsuses
    val bitmap = DataHolder.bitmap
    imageView.setImageBitmap(bitmap)
    DataHolder.bitmap = null // Pärast kasutamist puhastamine, kui vaja
    

    Tuleb arvestada rakenduse elutsüklit ja aktiivsust, mis võib olla taaskäivitamisel taastatud.

  3. Kasuta andmebaasi (Room) või muud salvestuslahendust:

    • Salvesta pilt (võib-olla byte-massiivina) andmebaasi.
    • Edasta andmebaasi kirje ID Intent kaudu.
    • Vastuvõttev aktiivsus loeb pildi andmebaasist ID järgi.
    // Esimeses aktiivsuses salvestamine (pseudo-kood Room jaoks)
    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)
    
    // Teises aktiivsuses lugemine (pseudo-kood Room jaoks)
    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. Kasuta jagatud ViewModel-i Navigation Component-iga:

    • Kui kasutatakse Navigation komponenti, saab kasutada ühise ViewModel, mis on seotud navigeerimisgraafi või aktiivsusega.
    • Andmed salvestatakse ViewModel-i ja on kättesaadavad teisele aktiivsusele.
    // ViewModel
    class SharedViewModel : ViewModel() {
        val imageBitmap = MutableLiveData<Bitmap>()
    }
    
    // Esimeses aktiivsuses (Navigation Component-iga)
    private val sharedViewModel: SharedViewModel by activityViewModels() // või by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.value = bitmap
    
    // Teises aktiivsuses
    private val sharedViewModel: SharedViewModel by activityViewModels() // või by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap ->
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap)
        }
    }
    

Valik sõltub kasutusstsenaariumist, andmete suurusest ja keerukusest. Piltide salvestamine faili (ja URI edastamine) või Singleton/ViewModel kasutamine on kõige sobivamad ja tõhusamad lahendused.