Sobes.tech
Middle

Ինչպես ճիշտ փոխանցել մեծ ծավալի տվյալներ, օրինակ՝ պատկեր, Android-ում ակտիվությունների միջև?

sobes.tech AI

Պատասխան AI-ից

Խոշոր տվյալների փոխանցումը, ինչպիսիք են պատկերները, անմիջապես Intent-ով խորհուրդ չի տրվում՝ տվյալների չափի սահմանափակման պատճառով, որը սովորաբար կազմում է մի քանի հարյուր կիլոբայթ կամ մեգաբայթ։ Շատ մեծ տվյալների փոխանցումը կարող է հանգեցնել TransactionTooLargeException-ի:

Լավագույն մոտեցումները՝

  1. Պատկերը պահել ֆայլում և ուղարկել ֆայլի ուղին 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)
    }
    
  2. Օգտագործել Singleton կամ գլոբալ տվյալների պահեստ:

    • Տվյալները պահել Singleton օբյեկտում կամ առանձին դասում, որը հասանելի է ցանկացած մասից։
    • Միջեւ ակտիվությունների փոխանցում ոչինչ չի պահանջվում, պարզապես դիմել Singleton-ին տվյալները ստանալու համար։
    // Գլոբալ օբյեկտ՝ օրինակ, Application դասում կամ առանձին սինգլտոնում
    object DataHolder {
        var bitmap: Bitmap? = null
    }
    
    // Առաջին ակտիվությունում
    DataHolder.bitmap = bitmap
    
    // Երկրորդ ակտիվությունում
    val bitmap = DataHolder.bitmap
    imageView.setImageBitmap(bitmap)
    DataHolder.bitmap = null // Օգտագործումից հետո մաքրում
    

    Պետք է հաշվի առնել հավելվածի կյանքի ցիկլը և ակտիվությունը, որը կարող է վերականգնվել։

  3. Օգտագործել տվյալների բազա (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)
        }
    }
    
  4. Օգտագործել 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- ի օգտագործումը, որոնք առավել արդյունավետ լուծումներ են։