Jak správně přenést velké množství dat, například obrázek, mezi aktivitami v Androidu?
sobes.tech AI
Odpověď od AI
Předat velkého objemu dat, jako je obrázek, přímo přes Intent se nedoporučuje kvůli omezení velikosti dat přenášených při serializaci (obvykle několik stovek kilobajtů nebo megabajtů). Přenos příliš velkých dat může vést k TransactionTooLargeException.
Správné přístupy:
-
Uložit data do souboru a předat cestu k souboru v
Intent.- Uložíme obrázek do dočasného souboru.
- Předáme URI nebo cestu k souboru v
Extraintentu. - Přijímající aktivita načte soubor podle obdržené cesty.
// Uložení v první aktivitě val imageUri: Uri = saveImageToFile(bitmap) // Funkce pro uložení Bitmap do souboru a vrácení Uri val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_uri", imageUri.toString()) startActivity(intent) // Čtení ve druhé aktivitě val imageUriString = intent.getStringExtra("image_uri") if (imageUriString != null) { val imageUri = Uri.parse(imageUriString) val bitmap = loadImageFromFile(imageUri) // Funkce pro načtení Bitmap z Uri imageView.setImageBitmap(bitmap) } -
Použít Singleton nebo globální úložiště dat.
- Umístíme data do Singleton objektu nebo do samostatné třídy, která je dostupná z libovolného místa v aplikaci.
- Není třeba předávat data mezi aktivitami, stačí odkazovat na Singleton pro získání dat.
// Globální objekt, například v třídě Application nebo v samostatném singletonu object DataHolder { var bitmap: Bitmap? = null } // V první aktivitě DataHolder.bitmap = bitmap // Ve druhé aktivitě val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Vyčištění po použití, pokud je potřebaJe třeba vzít v úvahu životní cyklus aplikace a aktivitu, která může být znovu vytvořena.
-
Použít databázi (Room) nebo úložiště dat (například SharedPreferences, i když pro obrázky není ideální).
- Uložit obrázek (možná ve formě byte pole) do databáze.
- Přenést identifikátor záznamu v databázi přes
Intent. - Přijímající aktivita načte obrázek z databáze podle ID.
// Uložení v první aktivitě (pseudo-kód pro 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) // Čtení ve druhé aktivitě (pseudo-kód pro 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žít sdílený ViewModel v Navigation Component.
- Pokud používáte Navigation Component, můžete použít sdílený
ViewModel, který je spojen s navigačním grafem nebo aktivitou. - Data jsou umístěna v
ViewModeljedné aktivity a jsou dostupná jiné.
// Ve ViewModel class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // V první aktivitě (při použití Navigation Component) private val sharedViewModel: SharedViewModel by activityViewModels() // nebo by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.value = bitmap // Ve druhé aktivitě private val sharedViewModel: SharedViewModel by activityViewModels() // nebo by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap -> if (bitmap != null) { imageView.setImageBitmap(bitmap) } } - Pokud používáte Navigation Component, můžete použít sdílený
Volba metody závisí na scénáři použití, velikosti dat a složitosti aplikace. U obrázků je často nejefektivnější uložit je do souboru (a předat URI) nebo použít Singleton/ViewModel, což jsou nejčastěji vhodná a efektivní řešení.