როგორ გადავცეთ სწორად დიდი მოცულობის მონაცემები, მაგალითად სურათი, Android-ის აქტივობებს შორის?
sobes.tech AI
პასუხი AI-სგან
დიდი მოცულობის მონაცემების, როგორიცაა სურათი, პირდაპირ Intent-ის საშუალებით გადაცემა რეკომენდებული არ არის, რადგან სერილიზაციის დროს მონაცემების ზომაზე შეზღუდვა არსებობს (საშუალოდ რამდენიმე ასეული კილობაიტი ან მეგაბაიტი). ძალიან დიდი მონაცემების გადაცემა შეიძლება გამოიწვიოს TransactionTooLargeException-ით.
სწორი მიდგომები:
-
მონაცემების შენახვა ფაილში და ფაილზე მისამართის გადაცემა
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) } -
გამოყენება Singleton ან გლობალური მონაცემთა შენახვისთვის:
- მონაცემები ინახება Singleton ობიექტში ან სხვა კლასში, რომელიც ხელმისაწვდომია ნებისმიერი ნაწილიდან.
- გადაცემის დროს არაფერია საჭირო, უბრალოდ მიმართეთ Singleton-ს მონაცემების მისაღებად.
// გლობალური ობიექტი, მაგალითად, Application კლასში ან დამოუკიდებელ სინგლტონში object DataHolder { var bitmap: Bitmap? = null } // პირველ აქტივობაში DataHolder.bitmap = bitmap // მეორე აქტივობაში val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // გამოყენების შემდეგ სუფთავება, თუ საჭიროაუნდა გაითვალისწინოთ აპლიკაციის სიცოცხლის ციკლი და აქტივობა, რომელიც შეიძლება იყოს გადაკეთებული.
-
გამოყენება მონაცემთა ბაზის (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) } } -
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-ის გამოყენება ყველაზე ხშირად არის ყველაზე ეფექტური და მოსახერხებელი გადაწყვეტილებები.