Sobes.tech
Middle

Kako pravilno preneti veliku količinu podataka, na primer sliku, između aktivnosti u Androidu?

sobes.tech АИ

Одговор од АИ

Пренос великих количина података, као што је слика, директно преко Intent се не препоручује због ограничења величине података који се преносе током серијализације (обично неколико стотина килобајта или мегабајта). Пренос превеликих података може довести до TransactionTooLargeException.

Правилни приступи:

  1. Сачувајте податке у фајл и пренесите пут до фајла у Intent.

    • Сачувајте слику у привремени фајл.
    • Пренесите URI или пут до фајла у Extra интента.
    • Активност која прима чита фајл по добијеном путу.
    // Складиште у првој активности
    val imageUri: Uri = saveImageToFile(bitmap) // Функција за чување Bitmap у фајл и враћање Uri
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtra("image_uri", imageUri.toString())
    startActivity(intent)
    
    // Читање у другој активности
    val imageUriString = intent.getStringExtra("image_uri")
    if (imageUriString != null) {
        val imageUri = Uri.parse(imageUriString)
        val bitmap = loadImageFromFile(imageUri) // Функција за учитавање Bitmap из Uri
        imageView.setImageBitmap(bitmap)
    }
    
  2. Користите Singleton или глобално складиште података.

    • Положите податке у Singleton објекат или посебну класу која је доступна са било које тачке у апликацији.
    • Нема потребе за преносом података између активности, једноставно се позива Singleton.
    // Глобални објекат, на пример у Application класи или посебном singleton-у
    object DataHolder {
        var bitmap: Bitmap? = null
    }
    
    // У првој активности
    DataHolder.bitmap = bitmap
    
    // У другој активности
    val bitmap = DataHolder.bitmap
    imageView.setImageBitmap(bitmap)
    DataHolder.bitmap = null // Чишћење након коришћења, ако је потребно
    

    Треба узети у обзир животни циклус апликације и активност која може бити поново креирана.

  3. Користите базу података (Room) или складиште података (на пример, SharedPreferences, иако за слике није идеално).

    • Сачувајте слику (можда као byte-низу) у базу података.
    • Пренесите идентификатор записа у бази података преко Intent.
    • Активност која прима чита слику из базе података по идентификатору.
    // Складиште у првој активности (псеудо-код за 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)
    
    // Читање у другој активности (псеудо-код за 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. Користите заједнички ViewModel у Navigation компоненту.

    • Ако користите Navigation компоненту, можете користити заједнички ViewModel повезан са графом навигације или активношћу.
    • Податке стављате у ViewModel једне активности и доступни су другој.
    // У ViewModel-у
    class SharedViewModel : ViewModel() {
        val imageBitmap = MutableLiveData<Bitmap>()
    }
    
    // У првој активности (када се користи Navigation компонент)
    private val sharedViewModel: SharedViewModel by activityViewModels() // или by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.value = bitmap
    
    // У другој активности
    private val sharedViewModel: SharedViewModel by activityViewModels() // или by navGraphViewModels(R.id.nav_graph)
    sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap ->
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap)
        }
    }
    

Избор метода зависи од сценарија употребе, величине података и сложености апликације. За слике, чување у фајл (и пренос URI) или коришћење Singleton/ViewModel често су најприкладнија и најефикаснија решења.