Kako pravilno preneti veliku količinu podataka, na primer sliku, između aktivnosti u Androidu?
sobes.tech АИ
Одговор од АИ
Пренос великих количина података, као што је слика, директно преко Intent се не препоручује због ограничења величине података који се преносе током серијализације (обично неколико стотина килобајта или мегабајта). Пренос превеликих података може довести до TransactionTooLargeException.
Правилни приступи:
-
Сачувајте податке у фајл и пренесите пут до фајла у
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) } -
Користите Singleton или глобално складиште података.
- Положите податке у Singleton објекат или посебну класу која је доступна са било које тачке у апликацији.
- Нема потребе за преносом података између активности, једноставно се позива Singleton.
// Глобални објекат, на пример у Application класи или посебном singleton-у object DataHolder { var bitmap: Bitmap? = null } // У првој активности DataHolder.bitmap = bitmap // У другој активности val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Чишћење након коришћења, ако је потребноТреба узети у обзир животни циклус апликације и активност која може бити поново креирана.
-
Користите базу података (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) } } -
Користите заједнички 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) } } - Ако користите Navigation компоненту, можете користити заједнички
Избор метода зависи од сценарија употребе, величине података и сложености апликације. За слике, чување у фајл (и пренос URI) или коришћење Singleton/ViewModel често су најприкладнија и најефикаснија решења.