Kā pareizi pārsūtīt lielu datu apjomu, piemēram, attēlu, starp aktivitātēm Android?
sobes.tech AI
Atbilde no AI
Liela apjoma datu, piemēram, attēla, tieša pārsūtīšana caur Intent nav ieteicama, jo datu izmēra ierobežojuma dēļ (parasti dažus simtus kilobaitu vai megabaitus). Pārsūtīt pārāk lielus datus var novest pie TransactionTooLargeException.
Pareizie pieejas veidi:
-
Saglabāt datus failā un pārsūtīt faila ceļu caur
Intent.- Saglabāt attēlu pagaidu failā.
- Pārsūtīt URI vai faila ceļu
Extra. - Saņemamā aktivitāte lasa failu pēc saņemtā ceļa.
// Pirmās aktivitātes saglabāšana val imageUri: Uri = saveImageToFile(bitmap) // Funkcija, kas saglabā Bitmap failā un atgriež URI val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_uri", imageUri.toString()) startActivity(intent) // Otrās aktivitātes lasīšana val imageUriString = intent.getStringExtra("image_uri") if (imageUriString != null) { val imageUri = Uri.parse(imageUriString) val bitmap = loadImageFromFile(imageUri) // Funkcija, kas ielādē Bitmap no URI imageView.setImageBitmap(bitmap) } -
Izmantot Singleton vai globālo datu glabātuvi:
- Datus glabā Singleton objektā vai citā klasē, kas ir pieejama no jebkuras programmas daļas.
- Starp aktivitātēm nav nepieciešams neko pārsūtīt, vienkārši piekļūstiet Singleton, lai saņemtu datus.
// Globālais objekts, piemēram, Application klasē vai atsevišķā singleton object DataHolder { var bitmap: Bitmap? = null } // Pirmās aktivitātes laikā DataHolder.bitmap = bitmap // Otrās aktivitātes laikā val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Notīrīt pēc lietošanas, ja nepieciešamsIr jāņem vērā programmas dzīves cikls un aktivitāte, kura var tikt pārveidota.
-
Izmantot datu bāzi (Room) vai citu datu glabātuvi (piemēram, SharedPreferences, lai gan attēliem tas nav ideāli):
- Saglabāt attēlu (iespējams, kā baitu masīvu) datu bāzē.
- Pārsūtīt datu bāzes ieraksta identifikatoru caur
Intent. - Saņemamā aktivitāte lasa attēlu no datu bāzes pēc identifikatora.
// Saglabāšana pirmajā aktivitātē (pseudo-kods 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) // Lasīšana otrajā aktivitātē (pseudo-kods 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) } } -
Izmantot Shared ViewModel Navigation Component-ā:
- Ja tiek izmantots navigācijas komponents, var izmantot kopīgu
ViewModel, kas ir saistīts ar navigācijas grafu vai aktivitāti. - Dati tiek glabāti
ViewModelvienā aktivitātē un ir pieejami citā.
// ViewModel class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // Pirmā aktivitāte (ar Navigation Component) private val sharedViewModel: SharedViewModel by activityViewModels() // vai by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.value = bitmap // Otrā aktivitāte private val sharedViewModel: SharedViewModel by activityViewModels() // vai by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap -> if (bitmap != null) { imageView.setImageBitmap(bitmap) } } - Ja tiek izmantots navigācijas komponents, var izmantot kopīgu
Izvēle ir atkarīga no lietošanas scenārija, datu lieluma un sarežģītības. Attēlu glabāšana failā (un URI pārsūtīšana) vai Singleton/ViewModel biežāk ir visefektīvākie un piemērotākie risinājumi.