Sobes.tech
Middle

როგორ გადავცეთ სწორად დიდი მოცულობის მონაცემები, მაგალითად სურათი, Android-ის აქტივობებს შორის?

sobes.tech AI

პასუხი AI-სგან

დიდი მოცულობის მონაცემების, როგორიცაა სურათი, პირდაპირ Intent-ის საშუალებით გადაცემა რეკომენდებული არ არის, რადგან სერილიზაციის დროს მონაცემების ზომაზე შეზღუდვა არსებობს (საშუალოდ რამდენიმე ასეული კილობაიტი ან მეგაბაიტი). ძალიან დიდი მონაცემების გადაცემა შეიძლება გამოიწვიოს TransactionTooLargeException-ით.

სწორი მიდგომები:

  1. მონაცემების შენახვა ფაილში და ფაილზე მისამართის გადაცემა Intent-ის საშუალებით:

    • სურათის შენახვა დროებით ფაილში.
    • URI ან ფაილის მისამართის გადაცემა Extra-ში.
    • მიმღები აქტივობა კითხულობს ფაილს მითითებული მისამართიდან.
    // პირველ აქტივობაში შენახვა
    val imageUri: Uri = saveImageToFile(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) // ფუნქცია, რომელიც იძენს სურათს URI-დან
        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) ან სხვა შენახვის საშუალების:

    • სურათის შენახვა (შესაძლოა, ბაიტების მასივის სახით) მონაცემთა ბაზაში.
    • მონაცემთა ბაზაში ჩანაწერის იდენტიფიკატორის გადაცემა Intent-ის საშუალებით.
    • მიმღები აქტივობა კითხულობს სურათს მონაცემთა ბაზიდან იდენტიფიკატორის მიხედვით.
    // პირველ აქტივობაში შენახვა (pseudo-კოდი 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-კოდი 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-ის გამოყენება ყველაზე ხშირად არის ყველაზე ეფექტური და მოსახერხებელი გადაწყვეტილებები.