Sobes.tech
Middle

Чӣ тавр дуруст интиқол додани миқдори зиёди маълумот, масалан тасвир, байни фаъолиятҳо дар Android?

sobes.tech AI

Ҷавоб аз AI

Перадача вялікага аб'ёму дадзеных, такіх як малюнак, непрадуктыўна рабіць непасрэдна праз 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 або асобным сінглтоне
    object DataHolder {
        var bitmap: Bitmap? = null
    }
    
    // У першай актыўнасці
    DataHolder.bitmap = bitmap
    
    // У другой актыўнасці
    val bitmap = DataHolder.bitmap
    imageView.setImageBitmap(bitmap)
    DataHolder.bitmap = null // Ачыстка пасля выкарыстання, калі трэба
    

    Неабходна ўлічваць жыццёвы цыкл прыкладання і актыўнасць, якая можа быць перазапушчана.

  3. Выкарыстоўваць базу дадзеных (Room) або сховішча дадзеных (напрыклад, SharedPreferences, хаця для малюнкаў не ідэальна).

    • Захоўваем малюнак (магчыма, у выглядзе байтавага масіва) у базе дадзеных.
    • Перадаем ідэнтыфікатар запісу ў базе дадзеных праз 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. Выкарыстоўваць Shared ViewModel у Navigation Component.

    • Калі выкарыстоўваецца кампанент навігацыі (Navigation Component), можна выкарыстоўваць агульную ViewModel, звязаную з графам навігацыі або актыўнасцю.
    • Дадзеныя змяшчаюцца ў ViewModel адной актыўнасці і даступныя іншай.
    // У ViewModel
    class SharedViewModel : ViewModel() {
        val imageBitmap = MutableLiveData<Bitmap>()
    }
    
    // У першай актыўнасці (з выкарыстаннем Navigation Component)
    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 з'яўляюцца найбольш прыдатнымі і эфектыўнымі рашэннямі.