Ինչպես ճիշտ փոխանցել մեծ ծավալի տվյալներ, օրինակ՝ պատկեր, Android-ում ակտիվությունների միջև?
sobes.tech AI
Պատասխան AI-ից
Խոշոր տվյալների փոխանցումը, ինչպիսիք են պատկերները, անմիջապես 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-ը բեռնելու համար imageView.setImageBitmap(bitmap) } -
Օգտագործել Singleton կամ գլոբալ տվյալների պահեստ:
- Տվյալները պահել Singleton օբյեկտում կամ առանձին դասում, որը հասանելի է ցանկացած մասից։
- Միջեւ ակտիվությունների փոխանցում ոչինչ չի պահանջվում, պարզապես դիմել Singleton-ին տվյալները ստանալու համար։
// Գլոբալ օբյեկտ՝ օրինակ, Application դասում կամ առանձին սինգլտոնում object DataHolder { var bitmap: Bitmap? = null } // Առաջին ակտիվությունում DataHolder.bitmap = bitmap // Երկրորդ ակտիվությունում val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Օգտագործումից հետո մաքրումՊետք է հաշվի առնել հավելվածի կյանքի ցիկլը և ակտիվությունը, որը կարող է վերականգնվել։
-
Օգտագործել տվյալների բազա (Room) կամ տվյալների պահեստ (օրինակ, SharedPreferences, թեև պատկերների համար դա իդեալական չէ)
- Պահել պատկերն (միգուցե՝ byte array ձևով) տվյալների բազայում։
- Հանձնել տվյալների բազայի գրառման նույնականացուցիչը
Intent-ով։ - Առաջարկող ակտիվությունը կարդում է պատկերն տվյալների բազայից ըստ նույնականացուցիչի։
// Առաջին ակտիվությունում պահպանում (pseudo-code for 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) // Երկրորդ ակտիվությունում կարդում (pseudo-code for 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) } } -
Օգտագործել Shared ViewModel Navigation Component-ով:
- Եթե օգտագործվում է նավիգացիայի կոմպոնենտը, կարելի է օգտագործել ընդհանուր
ViewModel, որը կապված է նավիգացիայի գրաֆի կամ ակտիվության հետ։ - Տվյալները պահվում են
ViewModel-ում և հասանելի են մյուս ակտիվությանը։
// ViewModel-ում class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // Առաջին ակտիվությունում (Navigation Component-ով) 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) } } - Եթե օգտագործվում է նավիգացիայի կոմպոնենտը, կարելի է օգտագործել ընդհանուր
Ընտրությունը կախված է օգտագործման սցենարից, տվյալների չափից և հավելվածի բարդությունից։ Պատկերների համար առավել հաճախ օգտագործվում է ֆայլում պահելը (և URI փոխանցելը) կամ Singleton/ViewModel- ի օգտագործումը, որոնք առավել արդյունավետ լուծումներ են։