Android'de aktiviteler arasında büyük veri miktarını, örneğin bir resmi, nasıl doğru şekilde aktarılır?
sobes.tech yapay zeka
AI'dan gelen yanıt
Intent aracılığıyla büyük veri hacimlerini, örneğin resmi doğrudan aktarmak önerilmez çünkü serileştirme sırasında aktarılan veri boyutu sınırına (genellikle birkaç yüz kilobayt veya megabayt) ulaşılır. Çok büyük verilerin aktarımı TransactionTooLargeException hatasına yol açabilir.
Doğru yaklaşımlar:
-
Verileri bir dosyaya kaydedin ve dosya yolunu
Intentile aktarın.- Resmi geçici bir dosyaya kaydedin.
- Dosyanın URI'sini veya yolunu
Extraolarak aktarın. - Alıcı aktivite, alınan yoldan dosyayı okur.
// İlk aktivitede kaydetme val imageUri: Uri = saveImageToFile(bitmap) // Bitmap'i dosyaya kaydeden ve Uri döndüren fonksiyon val intent = Intent(this, SecondActivity::class.java) intent.putExtra("image_uri", imageUri.toString()) startActivity(intent) // İkinci aktivitede okuma val imageUriString = intent.getStringExtra("image_uri") if (imageUriString != null) { val imageUri = Uri.parse(imageUriString) val bitmap = loadImageFromFile(imageUri) // Uri'den Bitmap yükleyen fonksiyon imageView.setImageBitmap(bitmap) } -
Singleton veya küresel veri deposu kullanın.
- Verileri Singleton nesnesine veya uygulama genelinde erişilebilir başka bir sınıfa koyun.
- Aktiviteler arasında herhangi bir şey aktarmaya gerek yok, doğrudan Singleton'dan erişilir.
// Uygulama veya ayrı bir singleton içindeki küresel nesne object DataHolder { var bitmap: Bitmap? = null } // İlk aktivitede DataHolder.bitmap = bitmap // İkinci aktivitede val bitmap = DataHolder.bitmap imageView.setImageBitmap(bitmap) DataHolder.bitmap = null // Kullanımdan sonra temizlemeUygulama ve aktivitenin yaşam döngüsünü dikkate almak önemlidir, çünkü aktivite yeniden oluşturulabilir.
-
Veritabanı (Room) veya diğer depolama çözümleri (SharedPreferences gibi, ancak resimler için ideal değil) kullanın.
- Resmi (muhtemelen byte dizisi olarak) veritabanına kaydedin.
- Veritabanı kaydının kimliğini
Intentile aktarın. - Alıcı aktivite, veritabanından kimlik kullanarak resmi okur.
// İlk aktivitede kaydetme (Room için psödokod) 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) // İkinci aktivitede okuma (Room için psödokod) 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) } } -
Navigation Component'te Paylaşılan ViewModel kullanın.
- Eğer Navigation Component kullanılıyorsa, ortak bir
ViewModelkullanılabilir, bu ViewModel navigation grafiği veya aktivite ile ilişkilendirilir. - Veriler, bir aktivitenin
ViewModel'ine konur ve diğerinde erişilebilir.
// ViewModel'de class SharedViewModel : ViewModel() { val imageBitmap = MutableLiveData<Bitmap>() } // İlk aktivitede (Navigation Component kullanırken) private val sharedViewModel: SharedViewModel by activityViewModels() // veya by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.value = bitmap // İkinci aktivitede private val sharedViewModel: SharedViewModel by activityViewModels() // veya by navGraphViewModels(R.id.nav_graph) sharedViewModel.imageBitmap.observe(viewLifecycleOwner) { bitmap -> if (bitmap != null) { imageView.setImageBitmap(bitmap) } } - Eğer Navigation Component kullanılıyorsa, ortak bir
Yöntem seçimi kullanım senaryosuna, veri boyutuna ve uygulama karmaşıklığına bağlıdır. Resimler için, dosyaya kaydetmek (ve URI'yi iletmek) veya Singleton/ViewModel kullanmak genellikle en uygun ve verimli çözümlerdir.