Hogyan lehet helyesen átadni nagy mennyiségű adatot, például egy képet, az Androidban az aktivitások között?
sobes.tech MI
Válasz az MI-től
Nagy mennyiségű adat, például kép közvetlen átadása az Intent segítségével nem ajánlott, mivel a serializálás során átadott adatmennyiség korlátozott (általában néhány száz kilobyte vagy megabájt). Túl nagy adatok átadása TransactionTooLargeException-hez vezethet.
Helyes megközelítések:
-
Adatok mentése fájlba és az útvonal átadása az
Intent-tel.- A képet ideiglenes fájlba mentjük.
- Az URI-t vagy az útvonalat az
Extra-ban adjuk át. - A fogadó aktivitás olvassa a fájlt a kapott útról.
// Mentés az első aktivitásban val imageUri: Uri = saveImageToFile(bitmap) // Függvény a Bitmap fájlba mentésére és Uri visszaadására val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_uri", imageUri.toString()) startActivity(intent) // Olvasás a második aktivitásban val imageUriString = intent.getStringExtra("image_uri") if (imageUriString != null) { val imageUri = Uri.parse(imageUriString) val bitmap = loadImageFromFile(imageUri) // Függvény a Bitmap betöltésére Uri-ból imageView.setImageBitmap(bitmap) } -
Singleton vagy globális adat tárolás használata.
- Az adatokat egy Singleton objektumba vagy külön osztályba helyezzük, amely mindenhol elérhető.
- Nincs szükség az adatok átadására aktivitások között, csak a Singleton-t kérjük le.
// Globális objektum, például az Application osztályban vagy külön singletonben object DataHolder { var bitmap: Bitmap? = null } // Az első aktivitásban DataHolder.bitmap = bitmap // A második aktivitásban val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Tisztítás használat után, ha szükségesFigyelembe kell venni az alkalmazás életciklusát és az aktivitás újraalkotását.
-
Adatbázis (Room) vagy adat tárolás használata (például SharedPreferences, bár nem ideális képekhez).
- A képet (esetleg byte-array-ként) elmentjük az adatbázisba.
- Az adatbázis rekord azonosítóját átadjuk az
Intent-tel. - A fogadó aktivitás azonosító alapján olvassa a képet az adatbázisból.
// Mentés az első aktivitásban (pseudo-kód Room-hoz) 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) // Olvasás a második aktivitásban (pseudo-kód Room-hoz) 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) } } -
Shared ViewModel használata a Navigation Component-ben.
- Ha a Navigation Component-et használod, akkor egy közös
ViewModel-t lehet alkalmazni, amely a navigációs gráfhoz vagy az aktivitáshoz kapcsolódik. - Az adatok az egyik aktivitásban kerülnek a
ViewModel-be, és elérhetőek a másik számára.
// A ViewModel-ben class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // Az első aktivitásban (Navigation Component esetén) private val sharedViewModel: SharedViewModel by activityViewModels() // vagy by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.value = bitmap // A második aktivitásban private val sharedViewModel: SharedViewModel by activityViewModels() // vagy by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap -> if (bitmap != null) { imageView.setImageBitmap(bitmap) } } - Ha a Navigation Component-et használod, akkor egy közös
A módszer kiválasztása a használati forgatókönyvtől, az adatok méretétől és az alkalmazás összetettségétől függ. Képek esetén a fájlba mentés (és URI átadása) vagy Singleton/ViewModel használata a leggyakoribb és leghatékonyabb megoldás.