-- android, java

Android :: Shared Preferences

Android veri depolama için birkaç farkı yöntem sunuyor. Bunları kendi sitesinde şöyle sıralamış:

  • Shared Preferences: Store private primitive data in key-value pairs.
  • Internal Storage: Store private data on the device memory.
  • External Storage: Store public data on the shared external storage.
  • SQLite Databases: Store structured data in a private database.
  • Network Connection: Store data on the web with your own network server.

Database kadar olmasa da shared preferences ufak tefek veri depolayıp/erişmek için kullanılası bir şey. Öyle büyük verilerle uğraşmadıkça database yerine tercih edilebilir.

Hash table yapısındaki gibi key-value prensibi ile çalışıyor farklı olarak yalnızca primitive tipler için kullanılabiliyor. Saklayabildiği tipler şunlar:

  • boolean
  • float
  • int
  • long
  • string

Çalıştığım projede böyle bir şey kullanma ihtiyacı duymuştum. Biraz araştırdıktan sonra işimi gördüm ama buraya da yazayım ki belki başkalarının da işine yarar bir gün.

Örnek bir uygulama üzerinde nasıl olacağını görelim. Öncelikle uygulamanın paylaşılan tercihlerine (bu şekilde çevirsem problem olmaz umarım) erişmek ve eğer daha önceden yoksa bir xml dosyası oluşturmamız gerekir. Verilerin yazıldığı dosya bir xml dosyası. Bunun için aşağıdaki kodu kullanabiliriz:

	SharedPreferences mSharedPrefs = getSharedPreferences("xmlFile",
				MODE_PRIVATE);

İlk parametre oluşacak dosyanın ismini, ikincisi de hangi modda olacağını belirtiyor. MODE_PRIVATE ile bu dosyanın sadece bizim uygulamamız tarafından erişilebileceğini belirttik. Bundan sonraki adım da dosyayı editlemek için erişmemiz gerekir. Aşağıdaki satır ile de bunu sağlıyoruz.

	SharedPreferences.Editor mPrefsEditor = mSharedPrefs.edit();

Artık dosyaya ulaştık. Buraya yukarda da belirttiğim gibi boolean, float, int, long ve/veya string veriler yazıp/okuyabiliriz. Yazmak için put, almak için de get metodları [putString(), getBoolean()…] zaten geliyor.

Örnek uygulamamızda, uygulamanın kaç defa çalıştığını ekranda göstermek istediğimizi düşünelim. Bunun için bir sayaç oluşturalım ve bu değeri paylaşılan tercihlerden okuyalım. Daha sonra da bir textView ile ekranda gösterelim.

	int mCounter = mSharedPrefs.getInt("counter", 0);

mCounter değişkenimize xmlFile içindeki “counter” isimli anahtarın değerini atıyoruz. getInt()[ve diğer getXXX] metodlarının aldığı ikinci parametre de default değer. Yani xml dosyası ortada yoksa ya da herhangi bir şekilde ordaki değeri alamazsak, default değerimiz geri dönüyor. Ayrıca dosyadan değer okumak için bir önceki satırdaki gibi editör oluşturmaya gerek yoktu. Editörü dosyaya yazmak için kullanacağız. Satırlar yer değişse ya da ikinci satır aradan çıksa da uygulama şimdilik çalışır.

Uygulamanın daha önce kaç defa çalıştırıldığını görmek için de aşağıdaki kodu yazıyoruz. Daha önceden main.xml içinde tanımladığımız textView nesnesinin text özelliğini, sayacımızın değeri ile güncelliyoruz.

	TextView tv = (TextView) findViewById(R.id.tvSampleTv);
	tv.setText("Uygulama daha önce " +String.valueOf(mCounter) + " defa çalıştırıldı.");

Uygulamamızı şimdi çalıştırırsak aşağıdakine benzer bir görüntü elde etmiş olmamız lazım.

Benim bu örnekte kullandığım main.xml de aşağıdaki gibi.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:orientation="vertical">
	<TextView android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:id="@+id/tvSampleTv"
		android:textStyle="bold"
		android:textColor="#FFFFFF"
		android:layout_gravity="center"></TextView>
</LinearLayout>

Sayfamız görüntülendiğine göre artık uygulamamız bir defa daha çalışmış oldu. Demek ki artık sayacı artırmamız gerekecek. Bunun için de aşağıdaki satırları yazalım.

	mPrefsEditor.putInt("counter", ++mCounter);
	mPrefsEditor.commit();

Nasıl database bağlantısı yapıp işlerimizi hallettikten sonra bağlantıyı kapatıyorsak, dosya açıp yazdıktan sonra dosyayı kapatıyorsak bunda da benzer bir durum (ama aynı değil tabi ki, sadece unutulmaması gereken bir şey olduğu için bu benzetmeleri yaptım. İntegral sınavlarındaki +c kadar önemli vallahi :)) olaraktan yaptıklarızı işlememiz lazım. commit() bunun için kullanıldı.

Uygulamayı bu haliyle çalıştırdığımızda yine ilk ekran görüntüsü gelecek. Yeni halini ilk defa çalıştırmış oluyoruz çünkü. Tekrar çalıştırdığımızda aşağıdaki,

üç defa daha çalıştırdıktan sonra da aşağıdaki görüntüye benzer şeyler görünmesi lazım.

Uygulamanın class kodu da aşağıdaki gibi şekillendi.

package com.oguz.example;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.TextView;

public class SharedPrefsExample extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		SharedPreferences mSharedPrefs = getSharedPreferences("xmlFile",
				MODE_PRIVATE);
		SharedPreferences.Editor mPrefsEditor = mSharedPrefs.edit();

		int mCounter = mSharedPrefs.getInt("counter", 0);

		TextView tv = (TextView) findViewById(R.id.tvSampleTv);
		tv.setText("Uygulama daha önce " + String.valueOf(mCounter)
				+ " defa çalıştırıldı.");

		mPrefsEditor.putInt("counter", ++mCounter);
		mPrefsEditor.commit();
	}
}

Şimdi bu uygulamayı yaptık da ne oldu? Evet pek bi ekşın yok ortada çünkü örnek seçimini pek sağlıklı yapmadım. Seçtiğim örnek anlatmak istediğim olaya pek uygun değil ama o kısmı da burda anlatsam herhalde eksiği tamamlarım. Uygulamada tek activity olduğu için pek bir yararını göremedik ama uygulamamızın içindeki tüm classlardan bu özelliklere erişip / değişiklik yapabileceğimizi bilmemiz belki getirdiği kolaylığı farketmemizi sağlayabilir. Üstelik ram gibi program boyunca kalıp tekrar başlatıldığında da kaybolmuyor. Uygulama cihazda bulunduğu sürece değerler korunuyor. Belki bu açıklama örnek seçimimdeki açığı biraz kapatmıştır :)

Oluşan xml dosyamızı da /data/data/paket.adi/shared_prefs altında bulabilir. En başta belittiğimiz moda göre erişim hakları düzenleniyor.

Yorum yazın

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.

23 Yorum

  1. teşekkürler Oğuz, güzel sade bir anlatım olmuş

  2. Peki ya sharefprefences dosyasının buluduğu konuma telefon kullanıcısı erişebiliyor mu? Hani, kullancıya bi tane xml versek kullancı file explorer vs kullanarak o dizine erişim o dosyayı uygun yere bırakabiliyor mu? yoksa root olmak mı gerekiyor bu işi yapabilmek için?

  3. @Mert
    Aklıma geldi ama denemedim hiç, ben de bilmiyorum maalesef.

  4. 03/11/2012 -> 16/04/2013 biraz geç oldu ama benim gibi siteyi yeni gören kişilerin öğrenmesi açısından güç olmasın diye düşünerek telefon kullanıcısının erişmesi için root olması lazım diyorum :)

  5. Bu arada Oğuz Bey’i kutlarım böyle yararlı bir site hazırladığı için, gerçi bazı yorumları ağır olmuş ama yaşına vermek lazım :)

  6. @Kenan,
    Öncelikle teşekkürler. Ağır olan yorumlar derken hangilerinden bahsediyoruz? Yaşımla ilgisi nedir onu da değerlendirmek lazım.

  7. Güzel bir anlatım olmuş elinize sağlık. Ben sadece android Studio da shared_prefs dosyasını bulamadım. Tam yeri nerde acaba ? Data klasörü yok çünkü bizde.

  8. @olkun
    Maalesef Android Studio kullanmadım henüz, orda nasıl bir yapı var bilmiyorum ama Eclipse’in sağladığı ekranda yazıda belirttiğim path ile erişilebiliyordu.

  9. Oğuz bey öncelikle teşekkürler böyle bir site için.Ben bir listview kullandım ve posiitona göre satıra tıklanıldığında setOnItemClicklistenerdaki view arg1 i her tıklamada satırın rengini soluklaştırıyor ama programı kapatıp tekrar açınca aynı kalmıyor nasıl çözebiirim bu sorunu.

  10. @Melisa
    SharedPreferences bu yapı için kullanılabilir. Renk bilgisi ya da satıra tıklanıp/tıklanmadığı bilgisi SharedPreferences içinde tutulup, adapter her çağrıldığında oradan kontrolü yapılabilir.

  11. Sade ve temiz anlatım. Teşekkürler. :)

  12. Selamlar,

    Üzerinden epey geçmiş ama belki bakıyorsunuzdur. Ben JSONdan gelen bir integer değerini sharedpreference ile tutmak istiyorum anlatılanları yaptım.

    Sorum şu olacak, ilk uygulama açıldığında JSONdan gelen değişkenin (adı a olsun) değeri a=1 olarak çekiliyor ve sharedpreference değişkenine (adı sp olsun) sp=1 olarak yazdırıyorum. Uygulamada bir karşılaştırma yapıyorum sp!=a ise bir şeyler yap diye, JSON güncellenince mesela a=2 olunca bu istediğim şey yapılıyor ancak merak ettiğim bu sefer sp değişkenine a’nın yeni değeri atılıyor mu yoksa hala sp=1 olarak kalıyor mu?

    Teşekkürler.

  13. @ufuk çakır,
    SharedPreferences’taki bir değerin değişmesi için commit etmen lazım. Senin örneğinde sp değişkeninin değeri sonradan değişiyor, eğer commit işlemini de uyguluyorsan değeri değişir yoksa herhangi bir değişiklik olmaz.

  14. Çok guzel anlatmıssınız ama bende bi hata verdi Tvsampletv kısmında neden oldugunu hala anlayamadım

  15. @Ebru:
    Hata mesajını ya da logcat çıktısını buraya yazabilir misiniz? Hatanın birden fazla sebebi olabilir, anlayabilmemiz için o çıktılara ihtiyacımız var.

  16. Merhabalar

    Ben android için veri tabanına(mysql) giriş çıkış yapan bir uygulama geliştiriyorum ve veri tabanından gelen verileri depolamak için SharedPreferences sınıfından yararlanıyorum.Sorunum şu login oluyorum kullanıcı bilgileri uygulama ana sayfasına geliyor ,diğer sayaflara geçiyorum yine geliyor tam istediğim gibi ,çıkış dugmesine bastığım zaman (clear metodunu çağırıp son olarak commit metodunu çağırıyorum) kullanıcı bilgileri siliniyor ve tekrar giriş yapmamı istiyor diğier sayfalardada aynı buraya kadar her şey tamam.

    Sorun şu ki login oluyorum çıkış düğmesi yerine fiziksel home dugmesine basıp ana menuye girip task managerdan uygulamayı kapatıpuygulamayı tekrar açtığım zaman en son giriş yapılan kullanıcının verileri geliyor(SharedPreferences nesnesindeki verileri temizlemediğimden dolayı) buna karşı nasıl bir önlem alabilirim ?
    teşekkurler.

  17. @Bilal Fedai
    Activity yaşam döngüsünü biraz incelersek soruna cevap bulabiliriz sanırım. Kısaca buraya bir göz atmakta fayda var: http://developer.android.com/guide/components/activities.html#ImplementingLifecycleCallbacks

    Ayrıca burdaki stackoverflow sorusuna verilen cevapta da home butonuna basıldığında ve tekrar geri dönüldüğünde sırası ile hangi metodların çalışacağından bahsedilmiş. http://stackoverflow.com/questions/5019686/what-methods-are-invoked-in-the-activity-lifecycle-in-the-following-cases

    Çok yüksek ihtimalle onStop() ve onStart() metodları içinde yapacağın kontroller ile problemini çözebilirsin.

  18. @Oguz Ozkeroglu
    Oğuz bey çok teşekkür ederim onStop() metodu sorunumu çozdü ,ben onDestroy() metodunu kullanıyordum zaten hatırladığım kadarıyla stackoverflow daki bazı konularda bu metodun her zaman çağrılacağının garanti olmadığı belirtilmişti , sadece yanlış yere odaklanmışım Teşekkürler tekrar :)

  19. anlatım gayet sade ve güzel. gereksiz bilgilere yer vermemiş ellerine sağlık kardeşim. çok işime yaradı

  20. Çok kaynaktan baktim7, videolar da izledim. hep havada kaldı. Sanıyorum siz adım adım ve mantık zincirinde akılcı bir yol izlediniz. Tebrik ediyorum sizi de kendimi de anladım olayı :)