Ako správne preniesť veľké množstvo údajov, napríklad obrázok, medzi aktivitami v Android?
sobes.tech AI
Odpoveď od AI
Prenos veľkého objemu dát, ako je obrázok, priamo cez Intent sa neodporúča kvôli obmedzeniu veľkosti dát prenášaných pri serializácii (zvyčajne niekoľko stoviek kilobajtov alebo megabajtov). Prenos príliš veľkých dát môže viesť k TransactionTooLargeException.
Správne prístupy:
-
Uložiť dáta do súboru a odovzdať cestu k súboru v
Intent.- Uložíme obrázok do dočasného súboru.
- Odovzdáme URI alebo cestu k súboru v
Extraintentu. - Prijímajúca aktivita načíta súbor podľa získanej cesty.
// Uloženie v prvej aktivite val imageUri: Uri = saveImageToFile(bitmap) // Funkcia na uloženie Bitmap do súboru a vrátenie Uri val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_uri", imageUri.toString()) startActivity(intent) // Čítanie v druhej aktivite val imageUriString = intent.getStringExtra("image_uri") if (imageUriString != null) { val imageUri = Uri.parse(imageUriString) val bitmap = loadImageFromFile(imageUri) // Funkcia na načítanie Bitmap z Uri imageView.setImageBitmap(bitmap) } -
Použiť Singleton alebo globálne úložisko dát.
- Uložíme dáta do Singleton-objektu alebo samostatnej triedy, ktorá je dostupná z ktorejkoľvek časti aplikácie.
- Pri prenose medzi aktivitami nie je potrebné nič odovzdávať, stačí sa odvolať na Singleton na získanie dát.
// Globálny objekt, napríklad v triede Application alebo samostatný singleton object DataHolder { var bitmap: Bitmap? = null } // V prvej aktivite DataHolder.bitmap = bitmap // V druhej aktivite val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Vyčistenie po použití, ak je potrebnéJe potrebné brať do úvahy životný cyklus aplikácie a aktivitu, ktorá môže byť znovu vytvorená.
-
Použiť databázu (Room) alebo úložisko dát (napríklad SharedPreferences, hoci pre obrázky nie je ideálne).
- Uložiť obrázok (možno vo forme byte poľa) do databázy.
- Odovzdať identifikátor záznamu v databáze cez
Intent. - Prijímajúca aktivita načíta obrázok z databázy podľa identifikátora.
// Uloženie v prvej aktivite (pseudokód pre 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) // Čítanie v druhej aktivite (pseudokód pre 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) } } -
Použiť Shared ViewModel v Navigation Component.
- Ak sa používa komponent navigácie (Navigation Component), môžete použiť spoločnú
ViewModel, ktorá je viazaná na navigačný graf alebo aktivitu. - Dáta sa ukladajú do
ViewModeljednej aktivity a sú dostupné druhej.
// Vo ViewModel class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // V prvej aktivite (pri použití Navigation Component) private val sharedViewModel: SharedViewModel by activityViewModels() // alebo by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.value = bitmap // V druhej aktivite private val sharedViewModel: SharedViewModel by activityViewModels() // alebo by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap -> if (bitmap != null) { imageView.setImageBitmap(bitmap) } } - Ak sa používa komponent navigácie (Navigation Component), môžete použiť spoločnú
Výber metódy závisí od scenára použitia, veľkosti dát a zložitosti aplikácie. Pre obrázky je najčastejšie vhodné uloženie do súboru (a odovzdanie URI) alebo použitie Singleton/ViewModel, ktoré sú najefektívnejšie riešenia.