Android : Localde Veri Saklamak {SharedPreferences}

Süleyman Sezer
HardwareAndro
Published in
5 min readSep 24, 2020

Uygulamaya giriş yaparken “Beni Hatırla”yı seçip giriş yapıyoruz. Verilerimiz (genelde email ve şifremiz) arka planda bir yerlerde bir şekilde tutuluyor. Peki bu veriler nerde tutuluyor, nasıl tutuluyor ve kaç farklı şekilde tutulabilir?

Gelin isterseniz önce kaç farklı şekilde tutulabilir sorusuyla başlayalım. Android’de verileri saklamak istersek temelde 4 farklı şekilde saklayabiliriz. Bunlar:

  • SharedPreferences ile saklamak
  • Dosya yazma işlemi yaparak verileri saklamak
  • Veritabanında bilgileri saklamak
  • Verileri uzak sunucuda tutmak

Biz bugün verilerimizi SharedPreferences kullanarak nasıl saklayabileceğimizi konuşacağız.

Öncelikle SharedPreferences nedir?

SharedPreferences, Android’de küçük verilerin basit ve kolay bir şekilde saklanmasını sağlar. Buradaki küçük veriler yani primitive type dediğimiz int, string, bool, char gibi tiplerdir. İş nesne saklamaya gelirse direkt nesneyi saklayamayız. Saklayabilmemiz için nesneyi jsona serileştirmemiz gerekir. Buradaki serileştirme işlemini GSON kullanarak kolayca yapabiliriz.

SharedPreferences’e veriler key-value olarak saklanmaktadır ve oluşturulan SharedPreferences dosyası, .xml uzantılı olarak depolanmaktadır.

SharedPreferences nasıl kullanılmaktadır?

SharedPref nesnesi oluşturma

Resimde görüldüğü iki farklı şekilde SharedPreferences nesnesi oluşturabiliyoruz. İlk kullanımda UserInfo.xml adında SharedPreferences dosyası oluşturalacak ve veriler bu XML’e yazılacak. İkinci kullanımdaysa SharedPreferences nesnesi hangi activity class”ında ise o isimle oluşturulacaktır. Örneğin biz bu SharedPreferences nesnesini MainActivity içerisinde oluştursak ve 2.kullanımda olduğu gibi isim vermeseydik oluşturulan XML’in ismi MainActivity.xmlolacaktı.

Eğer SharedPreferences ile saklanan veriler dosyalama şeklinde tutulacaksa 1.kullanım daha uygun olacaktır. Örneğin ayarlar için ayrı bir XML, kullanıcı bilgileri için ayri bir XML tutmak daha mantıklıdır.

Editor oluşturarak verileri saklıyoruz

SharedPreferences nesnesini kullanarak editor oluşturuyoruz ve put yardımıyla verilerimizi key-value olarak saklıyoruz.

Verileri yazma işlemi

Son olarak girilen verileri depolama alanına yazmamız gerekiyor. Ama burada iki farklı yöntem var. Bunlardan hangisini seçmeliyiz?

Commit ile Apply arasındaki fark nedir?

Commit işleminde main thread kullanılmakta ve verileri yazma işlemi synchronize bir şekilde çalışmaktadır. Bundan dolayı SharedPreferences diske yazılıncaya kadar kullanıcı arayüzünde bir işlem yapılamaz. Biz buna halk arasında ekran dondu diyebiliriz. Ekranda ögeler var ama işlem yapılamıyor çünkü arka planda bir takım işlemler gerçekleştirilmekte. Bunun çözümü içinse apply kullanılmaktadır. Apply işleminde verileri yazma işi background threadler ile yapılmakta ve asynchronize bir şekilde gerçekleşmektedir. Yani kullanıcı arayüzünde bir işlem yapılmaya devam ederken veriler arka planda yazılmaktadır.

SharedPrefe çok fazla veri girilirse ve bu işlem için commit kullanılırsa, main threadin yükü artacak olup kullanıcı arayüzünde uzun süre işlem yapılamayacaktır.Bundan dolayı da ANR hatası alınacaktır.

Sonuç olarak apply işlemi hem async olduğundan hem de background thread ile işlemlerini gerçekleştirdiğinden kullanılması önerilmektedir.

Peki verilerimizi nasıl okuyacağız?

SharedPreferences ile veri okuma işlemi

Nasıl ki verileri saklarken .put diyerek verileri ekliyorsak burada da .get diyerek verileri okuyoruz. Yalnız burada key-defaultValue şeklinde okuma yapıyoruz. Eğer girilen key ile eşleşen bir veri bulunamazsa defaultValue kısmına girilen değer bize dönecektir.

Verileri saklarken editor yardımıyla put işlemi yapıyoruz ama okuma işleminde direkt SharedPreferences nesnesi ile işlem yapıyoruz. UNUTMA !!!

Verileri sakladık. Peki nasıl sileceğiz?

SharedPreferences ile saklanan verileri silmek

Saklanan verileri silmek için remove içerisine key girerek silebilir veya clear diyerek tüm verileri silebiliriz. Yalnız burada da SharedPreferences nesnesinden oluşturulan bir editorle işlem yapılmaktadır.

SharedPreferences ile bir işlem yaptıktan sonra apply ile işlemi bitirmeyi unutma.

Basitmiş dedik, güldük eğlendik. Peki ya bir verinin değişip değişmediğini dinlemek istiyorsak ne yapmalıyız?

SharedPref dinleyicisi

Oluşturmuş olduğumuz SharedPreferences objesini dinlememiz gerekiyor. Bunun için registerOnSharedPreferenceChangeListener metodunu kullanmamız gerekiyor. Buradaki _sharedPref bizim SharedPreferences nesnemizi, key ise değeri değişen verinin keyini bize veriyor. If bloğu kullanarak veri değişirse yapılacak işlemleri burada yapabiliriz.

Ancak:

BU KULLANIM DOĞRU DEĞİLDİR. ÇÜNKÜ BU KULLANIM WEAK REFERENCE KULLANIMINA GİRMEKTEDİR.

Weak Reference nedir?

Weak Reference, garbage collector ile alakalı bir kavramdır. Garbage collector derlenmiş olan kodda kullanılmayan değişkenleri ve referansı olmayan objeleri bellekten silmektedir. Oluşturmuş olduğumuz her bir nesnenin veya bize değer döndüren metotun bir referans adresi vardır. Eğer biz bu referans adresini bir nesnede saklarsak garbage collector bu nesneyi silmeyecektir. Ne zaman ki bu nesne erişilemeyecek duruma geçer veya kapsam dışına çıkar o zaman garbage collector bu nesneyi ve reference adresini o zaman temizleyecektir.

Bu yüzden yukarıdaki gibi işlem yaparsak yani döndürdüğü reference değerini bir objede saklamazsak, garbage collector ne zaman memory şişmeye başlarsa bu kodu temizlemeye çalışacak, yani uygulamamızda bu kod bazen çalışacak bazen çalışmayacaktır.. Bundan dolayı bu kullanım yerine şöyle kullanmalıyız :

OnSharedPreferenceChangeListener strong reference

OnSharedPreferenceChangeListener metodunun reference değerini bir nesnede tutup bunu register ederken veermeliyiz. Bu sayede strong reference kullanımı yapmış oluyoruz.

Ayrıca bu oluşturduğumuz listeneri onResume lifecyclesinde register, onPause lifecyclesinde unRegister yapmamız gerekiyor.

on resume ve on pausede register ve unregister etme

Bu işlemi onResume’de yapma sebebimiz SharedPreferences’e veri kaydederken apply diyoruz. Bu işlem async olarak onCreate lifecyclesinde yapılmakta. Yani sonucu ne zaman döneceği belli değil. Ayrıca bu işlem bitmeden de onCreate adımı bitmiyor. Yani onCreate -> onStart -> onResume adımına geçildiğinde veri yazma işlemi bitmiş ve register edilip üzerindeki değişiklikleri dinlenmeye hazır hale geliyor. Bundan dolayı onResume’de register ediyor, onPause’de unRegister yapıyoruz.

Son olarak :

  • SharedPreferences activity ayaktayken oluşturulmaktadır. Yani onCreate içerisinde oluşturulması gerekir. Eğer bir classın içerisinde oluşturulursa contexte erişemediği için null hatası döndürmektedir.
  • Ayrıca eğer memory dolduysa ve garbage collector tarafından bir şeylerin silinmesi gerekiyorsa öncelikli olarak weak reference olan kodlar silinir. Bunun yerine yukarıdaki gibi strong reference kodlar kullanmalıyız.

--

--

Süleyman Sezer
HardwareAndro

Native Android Developer at Anadolu Hayat Emeklilik