Sync Adapter Kullanarak Veri Taşımak :MobileCoder I MobileCoder.NET I Mobil Programlama I Android Programlama I Mobil Geliştiricilerin Buluşma Noktası I www.MobileCoder.Net

Sync Adapter Kullanarak Veri Taşımak

04.04.2015 tarihinde Android Programlama kategorisine eklenmiş, 152 views Kişi Okumuş ve 0 Yorum Yapılmış.

Sync Nedir ? Ne işe Yarar?

Öncelikle İngilizce kökenli olan “Sync” kelimesi Türkçe de;

“Senkronize etmek,eşitlemek,ses ve hareketi eş zamanlı yapmak” anlamına gelir.

Cihaz ile web sunucusu arasında veri eşitlemesi yapmak, uygulamamız açısından kullanışlı bir özelliktir. Bunun yanında kullanıcılarımız açısından saygı uyandırıcı bir özelliktir. Örneğin, uygulamamızdaki verileri bir web sunucusuna yedeklemek, yedek alma açısından işlevseldir. Aynı şekilde verileri sunucudan almak da kullanıcının cihazı çevrim dışı olduğunda verilere erişimi açısından kullanışlı bir senaryodur. Bazı durumlarda kullanıcılar, verilerini bir web ara yüzünden girmeyi ve düzenlemeyi kullanışlı bulurlar. Ardından o verileri cihazlarında kullanılabilir halde bulmaktan da mutluluk duyarlar. Aynı şekilde, zamanla biriktirdikleri verileri bir arada toplamak ve onları merkezi bir depolama alanına yüklemek hoşlarına gider.

Android’in Sync Adapter altyapısı, veri aktarımlarını yönetmenize ve otomatikleştirmenize yardımcı olur, farklı uygulamalar arasındaki veri eşleme işlemlerini koordine etmenizi sağlar. Bu geliştirme çatısını kullanacağınız zaman, kendi yapınızla veri eşleme yapmayı denediğinizde yapamayacağınız bazı önemli özellikleri kazanırsınız:

Eklenti mimarisi: Veri aktarım kodunuzu, çağırılabilir bazı bileşenlerle doğrudan sisteme eklemenize olanak sağlar.

Otomatikleştirilmiş Çalışma: Veri aktarımlarını belli koşullara göre otomatikleştirmenize olanak sağlar. Örneğin veri ağı değişimi (Wi Fi-Mobil veri gibi), geçen zaman veya günün belli bir saati bu koşullardan biri olabilir. Ek olarak sistem, bir kuyrukta çalıştırılması zor olan aktarımları kuyruğa alır ve cihaz müsait olduğunda çalıştırır.

Otomatikleştirilmiş Ağ Denetimi: Sistem veri aktarımlarınızı sadece cihaz ağa bağlandığında çalıştırmanıza olanak sağlar.

Artırılmış Batarya Ömrü: Uygulamanızın veri aktarım görevlerini tek bir yerde toplamanıza olanak sağlar ve böylece hepsi aynı anda çalıştırılabilir. Veri aktarımlarınız aynı zamanda diğer uygulamaların veri aktarımlarıyla birlikte çalışmak üzere zamanlanır. Tüm bu faktörler sayesinde sistemin batarya kullanımını artıran ağ bağlantısı aç/kapa işlemlerinin sayısı azalacaktır.

Hesap Yönetimi ve Hesap Doğrulaması: Eğer uygulamanız sunucuda oturum açmak için bazı kullanıcı bilgileri gerektiriyorsa, böyle bir durumda isterseniz veri aktarımlarınızın içinde hesap yönetimi ve doğrulamasını ekleyebilirsiniz.

NOT: Sync Adapter’lar eş zamansız (asenkron) çalışır ve bu nedenle veri aktarımlarınızı düzenli ve verimli yapmasını bekleyebilir fakat anında gerçekleştirmesini bekleyemezsiniz. Uygulamanızın gerçek zamanlı bir veri aktarım ihtiyacı olacaksa, orada bu işlemi AsyncTask veya bir IntentService ile yapmalısınız.

Sıradaki konumuz Stub Authenticator Oluşturmak , Sync Adapter çatısı, uygulamamızın parçası olarak bir hesap yöneticisi tanımlamamızı bekler. Bu bileşeni nasıl ekleyeceğimizi göreceğiz. Basitlik açısından bir “stub authentication” bileşenini nasıl oluşturacağımızı inceleyeceğiz.

Stub Authenticator Oluşturmak

Sync Adapter çatısı, Sync Adapter’ımızın, veri aktarım işini, bir hesapla ilişkilendirilmiş depolama alanı ve giriş için izin gerektiren sunucu arasında yaptığımızı varsayar. Bu nedenle çatı, Sync Adapter’ımızın bir parçası olarak “Authenticator” (Doğrulayıcı) isimli bir bileşeni sağlamamızı bekler. Bu bileşen Android hesaplarını ve kimlik doğrulama çatısını birleştirir ve kullanıcının giriş bilgileri gibi bilgilerini yönetmek için standart bir ara yüz sunar.

Uygulamamız kullanıcı hesaplarını (Cihazda kayıtlı olan) kullanmıyorsa bile bir doğrulayıcı bileşeni oluşturmamız gerekiyor. Eğer kullanıcı hesaplarını kullanmıyorsanız veya sunucu girişi yapmıyorsanız, doğrulayıcı tarafından idare edilen bilgi es geçilir ve bu sayede belli bağlantı işlerini gerçekleştiren ufak tefek metotları olan bir doğrulayıcı sağlayabiliriz. Bir yandan da bir Service’e ihtiyacımız var. Bu servis, Sync Adapter’ın doğrulayıcının metotlarını çağırmasını sağlar.

Bir kimlik doğrulama (authenticator) aracısı bileşeni eklemek

Uygulamanıza bir kimlik doğrulama aracısı bileşeni eklemek için AbstractAccountAuthenticator sınıfından türeyen bir sınıf oluşturun ve bütün gerekli metodları null döndürerek ya da hata fırlatarak devre dışı bırakalım.

Aşağıdaki kod parçası Stub Authenticator sınıfının bir örneğini göstermektedir:resim1

Doğrulayıcıyı uygulama çatısına bağlamak (Binding)

Sync Adapter çatısının doğrulayıcımıza erişmesini sağlamak için mutlaka bir servis (bound service) yazmalıyız. Bu servis, uygulama çatısının doğrulayıcımıza ulaşmasını ve aralarında veri aktarımı yapmasını sağlayan bir Android bağlayıcı (Binder) nesnesi oluşturur.

Uygulama çatısı bu Service’i ilk kez doğrulayıcıya (authenticator) erişim ihtiyacı olduğunda başlattığından dolayı, kendimiz doğrulayıcıyı örneklemek (instantiate) istediğimizde Service.onCreate() metodunun içinde doğrulayıcının (authenticator) yapılandırıcısını çağırabiliriz.

Aşağıda ki kod parçası Service’i nasıl tanımlayacağımızı gösterir:resim2

Doğrulayıcı metadata dosyası eklemek

Doğrulayıcı bileşenimizi Sync Adapter’a ve kullanıcı hesabı çatısına (Account Framework) eklemek için bu çatılara bileşenimizi tanıtan bir metadata koymalıyınız. Bu metadata, Sync Adapter için yarattığımız hesabın tipini ve bunu kullanıcıya görünür kılmak için gerekli kullanıcı arayüzü elemanlarını tanımlar. Bu metadatayı/res/xml yolunda bulunan XML dosyası içinde tanımlayalım. Dosyaya istediğimiz ismi verebiliriz. Varsayılan olarak authenticator.xml olarak tanımlanmıştır.

Bu XML dosyası tek bir <account-authenticator> elementi içerir. Bu element de aşağıdaki değerleri içerir:

android:accountType

Sync adapter çatısı her bir Sync Adapter için alan adı formatında bir hesap adı bilgisine ihtiyaç duyar. Çatı bu hesap tipini Sync Adapter’in dâhili kimliği olarak kullanır. Giriş yapmayı gerektiren sunucular için hesap tipi bir kullanıcı hesabıyla birlikte sunucuya giriş referansı olarak gönderilir.

Sunucunuz giriş yapmayı gerektirmiyorsa da bir hesap tipi yaratmanız gerekir. Değeri içinse kontrolünüzdeki alan adını kullanın. Çatı bu değeri sadece Sync Adapter’inizi yönetmek için kullanacak, sunucuya göndermeyecek.

Android:icon

Simge içeren Drawable kaynağını gösterir. Eğer Sync Adapter’ınızı res/xml/syncadapter.xml dosyası içinde android:userVisible=”true” şeklinde görülebilir yapıyorsanız, bu simgeyi mutlaka kaynağa koymalısınız. Sistemin Ayarlar sekmesindeki Hesaplar kısmında görünür.

android:smallIcon

Küçük simge içeren Drawable kaynağını gösterir. Bu kaynak ekran büyüklüğüne göre Ayarlar bölümündeki Hesaplar kısmında ofandroid:icon’ın yerine kullanılabilir.

android:label

Hesap tipini kullanıcılara gösteren yerelleştirilebilen string’tir. Eğer Sync Adapter’ınızı res/xml/syncadapter.xml dosyası içinde android:userVisible=”true” şeklinde görülebilir yapıyorsanız, bu string’i mutlaka kaynağa koymalısınız. Sistemin Ayarlar sekmesindeki Hesaplar kısmında doğrulayıcı için tanımladığınız simgenin yanında gözükür.

Aşağıdaki kod parçası daha önce doğrulayıcı için yarattığınız XML dosyasını gösterir:resim3

Doğrulayıcıyı manifest içinde belirtmek

Bir önceki adımda, doğrulayıcıyı Sync Adapter çatısına bağlayan Service’i yazdık. Bu servisi sisteme tanıtmak için app manifest dosyanızda <application> elemanının altına aşağıdaki <service> elemanını ekleyelim:resim4

intent-filter> elemanı, doğrulayıcıyı çalıştırmak için sistem tarafından gönderilen actionandroid.accounts.AccountAuthenticator uyarısı ile kontrol edilen bir filtre tanımlar. Filtre uyarıldığı zaman sistem doğrulayıcıyı sarmak için yarattığımız servis olan AuthenticatorService’i başlatır.

<meta-data> elemanı, doğrulayıcınız için metadatayı tanımlar. android:name özelliği meta-data’yı doğrulayıcı çatısına bağlar. android:resource elemanı daha önce yarattığımız doğrulayıcı metadata dosyasının ismini belirler.

Doğrulayıcının yanında Sync Adapter da bir içerik sağlayıcıya ihtiyaç duyar. Eğer uygulamamız bir içerik sağlayıcı kullanmıyorsa, bir sonraki eğitim içeriğine gidip bir Stub Content Provider nasıl yaratılır. Eğer uygulamanız bir içerik sağlayıcı zaten kullanıyorsa Creating a Sync Adapter eğitim içeriğine gidin.

Bir Aracı İçerik Sağlayıcısı Oluşturmak

Sync Adapter çatısı, esnek ve çok güvenli bir içerik sağlayıcı çatısı tarafından üretilmiş cihaz verisiyle çalışmak için tasarlanmıştır. Bu sebeple sync adapter çatısı, yerel veri için önceden tanımlanmış içerik sağlayıcı çatısı kullanan bir uygulamaya ihtiyaç duyar. Eğer sync adapter çatısı sync adapter’imizi çalıştırmayı dener de uygulamamız bir içerik sağlayıcıya sahip olmazsa, sync adapter’imiz çöker.

Eğer sunucudan cihaza veri aktarımı yapan yeni bir uygulama geliştiriyorsak, yerel verimizin bir içerik sağlayıcı içinde korunduğunu dikkate almalıyız. Sync adapter’lerimizin öneminin yanında, içerik sağlayıcılar çeşitli güvenlik faydaları sağlar ve Android sistemlerdeki veri depolamasını yönetir.

Yerel verimizi zaten başka bir tipte saklıyorsak, o zaman sync adapter’i veri aktarımı işi için kullanabiliriz. İçerik sağlayıcı için gereken sync adapter çatısı ihtiyacını karşılamak için uygulamamıza aracı içerik sağlayıcısı (stub content provider) eklemeliyiz. Bir aracı sağlayıcı, içerik sağlayıcı sınıfını yaratır ancak bütün gerekli metotları null ya da 0 döndürür. Eğer bir aracı sağlayıcı eklersek, istediğiniz hafıza yöntemini kullanarak veri aktarmak için sync adapter’i kullanabiliriz.

Eğer uygulamanızda zaten bir içerik sağlayıcı varsa, aracı içerik sağlayıcıya ihtiyacınız yok demektir.Fakat içerik sağlayıcımız yoksa şimdi bunu nasıl elde edeceğimizi öğreneceğiz. 

Bir aracı içerik sağlayıcısı eklemek

Uygulamanıza aracı içerik sağlayıcısı eklemek için, ContentProvider sınıfını genişletip, gerekli metotları geçersiz kılmak gerekir. Aşağıdaki kod parçası bir aracı sağlayıcıyı nasıl yaratacağınızı gösterir:

resim5

Sağlayıcıyı Manifest’te belirtmek

Sync adapter çatısı, uygulamamızın manifest’ine bakarak uygulamanın içerik sağlayıcıya sahip olup olmadığını tespit eder. Aracı sağlayıcıyı manifest’te tanımlamak için dosyaya aşağıdaki değişkenlere sahip bir <provider> elemanı eklemmiz gerekir:

  • android:name=”com.example.android.datasync.provider.StubProvider”:Aracı içerik sağlayıcıyı yürüten sınıfın tam ismini belirtir.
  • android:authorities=”com.example.android.datasync.provider”: Aracı içerik sağlayıcıyı tanıtan URI yetkilisidir. Bu değeri, uygulamamızın paket isminin sonuna “.provider” koyarak elde ettiğimiz string yapalım. Sisteme kendi aracı sağlayıcımızı tanıtsanız bile hiçbir şey sağlayıcıya kendi erişmeye çalışmaz.
  • android:exported=”false”: Diğer uygulamarın içerik sağlayıcıya ulaşıp ulaşamayacağına karar verir. Aracı içerik sağlayıcımız için bu değeri “false” atayalım çünkü diğer uygulamaların sağlayıcıya ulaşmasına gerek yoktur. Bu değer, sync adapter çatısı ile içerik sağlayıcı arasındaki etkileşimi etkilemez.
  • android:syncable=”true”:Sağlayıcının eş zamanlanabilir olduğunu belirten bir bayraktır. Bu bayrağı “true” atarsak kodumuzda callsetIsSyncable() metodunu çağırmamıza gerek yoktur. Bu bayrak, sync adapter çatısının içerik sağlayıcı ile veri aktarımı yapmasına izin verir ancak aktarım sadece siz dışarıdan izin verdiğimizde çalışır.

Aşağıdaki kod parçası, <provider> elemanını nasıl uygulama manifest’ine ekleneceğini gösterir:resim6

Artık sync adapter çatısı tarafından ihtiyaç duyulan değişkenleri yarattık, şimdi veri aktarım kodumuzu kapsayan bir bileşen yaratabiliriz. Bu bileşene “sync adapter” adı verilir. Şimdi içeriği bu bileşeni uygulamamıza nasıl ekleyeceğimizi anlatacağız.

Sync Adapter Oluşturmak

Uygulamamızdaki Sync Adapter bileşeni, cihazımız ve sunucu arasında veri aktarımı yapan görevler için gerekli kodu kapsar. Sync adapter çatısı kodu, uygulamamızdaki zamanlama ve tetikleyicilere göre sync adapter bileşenimizin içinde çalıştırır. Uygulamamıza sync adapter bileşeni eklemek için aşağıdaki bileşenleri eklememiz gerekir:

Sync Adapter Sınıfı: Veri aktarım kodunu sync adapter çatısıyla uyumlu bir interface içine saran sınıf.

Bound Service: Sync adapter çatısının, kodumuzu sync adapter sınıfında çalıştırmasını sağlayan bileşendir.

Sync Adapter XML metadata dosyası: Sync adapter’imiz hakkında bilgi saklayan dosyadır. Çatı veri transferimizin zamanlamasını yapmak ve nasıl yükleme yapılacağını öğrenmek için bu dosyayı okur.

App manifest içindeki ifadeler: Bound Service’i tanımlayan bir XML’dir ve sync adapter’in belirlenmiş metadatasını işaret eder.

Sync Adapter sınıfı yaratmak

Bu kısmında veri aktarım kodunu kapsayan bir sync adapter sınıfını nasıl oluşturacağımızdan bahsedeceğiz. Bu sınıf oluşturmanın içine, temel sync adapter sınıfından türetmek, bu sınıfın yapılandırıcılarını tanımlamak ve veri aktarımı görevlerini tanımladığımız bir metod oluşturmak dahildir.

Temel AbstractThreadedSyncAdapter sınıfından türemek: Sync adapter bileşeni oluşturmaya AbstractThreadedSyncAdapter sınıfından türemekle ve onun yapılandırıcılarını yazmakla başlamalıyız. Sync adapter bileşenimiz sıfırdan her oluşturulduğunda, yapılandırıcılar kurulum görevlerini çalıştırmak için kullanacağız. Tıpkı bir activity kurmak için Activity.onCreate()’i kullandığımız gibi. Örneğin, uygulamamız veri saklamak için bir içerik sağlayıcı kullanıyorsa ContentResolver instance’ini almak için yapılandırıcıları kullanmalıyız. Android 3.0’de parallelSyncs argümanını desteklemek için ikinci bir yapılandırıcı tipi eklendiğinden, uyumluluğu sağlamak için bizim de iki tip yapılandırıcı oluşturmamız gerekir.

Not: Sync adapter çatısı, singleton instance olan sync adapter bileşenleriyle çalışmak için tasarlanmıştır.

Aşağıdaki kod bloğu, AbstractThreadedSyncAdapterand yapılandırıcılarının nasıl yazılacağını göstermektedir:

resim7

Veri transfer kodunu onPerformSync()’e eklemek

Sync adapter bileşeni kendiliğinden veri aktarımı yapmaz. Onun yerine veri transfer kodumuzu kapsar, dolayısıyla sync adapter çatısı veri transferimizi uygulamamızdan etkileşim almadan arka planda gerçekleştirebilir. Çatımız uygulamamızın verisini eşlemeye hazır olduğunda yazdığımız onPerformSync() metoduna başvurur.

Uygulamamızın ana kodundan sync adapter bileşenine veri transferini rahatlatmak için, sync adapter çatısı onPerformSync() metodunu aşağıdaki argümanlarla çağırır:

Hesap (Account): Sync adapter’i tetikleyen bir event ile bağlantılı bir hesap nesnesidir. Eğer sunucumuz hesapları kullanmıyorsa, bu nesnedeki bilgileri kullanmamıza gerek yoktur.

Ekler (Extras): Sync adapter tarafından tetiklenmiş eventten gelen bayrakları taşıyan Bundle’dır.

Yetkili(Authority): Sistemimizdeki içerik sağlayıcının yetkilisidir. Uygulamamızın bu sağlayıcıya erişimi olmalıdır. Genelde, yetkili uygulamamızdaki içerik sağlayıcıya eşdeğerdir.

İçerik Sağlayıcı İstemci (Content provider client): Yetkili argümanı tarafından içerik sağlayıcıya yöneltilmiş bir ContentProviderClient’dır. Hafif, herkese açık içerik sağlayıcı interface’idir. ContentResolver ile aynı temel fonksiyonlara sahiptir. Uygulamamız için veriyi içerik sağlayıcı kullanarak saklıyorsak, sağlayıcıya bu nesne ile bağlanabiliriz. Kullanmıyorsak da görmezden gelebiliriz.

Eşzamanlama Sonucu (Sync result):  Sync adapter çatısına bilgi göndermek için kullandığınız SyncResult nesnesidir.

Aşağıdaki kod parçası onPerformSync()’in genel yapısını gösterir:resim8

onPerformSync()’in gerçek yazımı, uygulamamızın eş zamanlama gerekliliklerine ve sunucu bağlantı protokollerine özel olduğu için, kodumuzun gerçekleştirmesi gereken birkaç genel görev vardır:

Sunucuya bağlanmak: Veri aktarımımız başladığında bağlantının uygun olduğunu varsaysak bile sync adapter çatısı sunucuya otomatik olarak bağlanmaz.

Veri indirmek ve yüklemek: Bir sync adapter veri aktarma görevlerini otomatize etmez. Sunucudan veri indirmek ve bir içerik sağlayıcıda tutmak istiyorsak, veriyi isteyen, indiren ve sağlayıcıya koyan bir kod yazmamız gerekir. Aynı şekilde eğer sunucuya veri yüklemek istiyorsak, veriyi dosyadan, veritabanından ya da sağlayıcıdan okuyup gerekli yükleme isteği yapan bir kod yazmamız gerekir.

Veri çakışmalarını yakalayıp mevcut veriye karar vermek: Bir sync adapter sunucudaki ve cihazdaki verilerin arasındaki çakışmayı otomatik olarak yakalamaz. Aynı zamanda cihazdaki verinin sunucudakinden yeni ya da eski olduğunu da otomatik olarak fark etmez. Bizim bu durumları çözecek bir algoritma yazmamız gerekir.

Temizlik: Her veri transferinin sonunda bağlantıları kapatıp, temp dosyalarını ve önbelleği temizlememiz gerekir.

Not: Sync adapter çatısı onPerformSync()’i bir arkaplan iş parçacığı üzerinde çalıştırır. Dolayısıyla kendimiz arka plan işlemi kurmak zorunda kalmayız.

Eş zamanlama bağlantılı görevlerimize ek olarak düzenli bağlantıyla alakalı görevlerimizi düzenlememiz ve onPerformSync()’e eklememiz gerekir. Bütün bağlantı görevlerimizi bu metod içinde düzenleyerek bağlantı kurmak ve bitirmek için gerekli interface’lerin harcadığı batarya ömrünü kazanırız.

Sync Adapter’i bir çatıya bağlamak

Artık veri aktarım kodumuz bir sync adapter bileşeni tarafından kapsanmış durumda ama kodumuza erişim sağlayan bir çatı da oluşturmak zorundayız. Bunu yapmak için sync adapter bileşeninden çatısına özel bir Android binder nesnesi yollayan bound Service oluşturmalıyız. Bu binder nesnesiyle, çatı onPerformSync() metodunu tanıyabilir ve içine veri yollayabilir.

Sync adapter bileşenini servis içindeki singleton onCreate() metodu olarak kanıtlamamız gerekir. Bu sayede, oluşturmayı servis başlayıncaya kadar erteleyebiliriz. Bu da çatı, veri aktarımımızı ilk kez denendiği zaman gerçekleşir. Sync adapter çatısı birden fazla çalıştırmayı sync adapterinize tetikletmeye veya zamanlatmaya çalışırsa diye bu kanıtlamayı iş parçacığını koruyacak şekilde yapmalıyız.

Örneğin, aşağıdaki kod parçası bound Service’i yaratan sınıfı nasıl oluşturacağımızı gösterir, sync adapter bileşenimizi kanıtlar ve Android binder nesnesini alır:resim9resim10

Çatı için gereken hesabı eklemek

Sync adapter çatısı her sync adapterinin bir hesap tipi olmasına ihtiyaç duyar. Hesap tipi değerini Doğrulayıcıyı Metadata Dosyasına Eklemek bölümünde atadık. Şimdi, bu hesap tipini Android sisteminizde de kaydetmemiz gerekecek. Bunun için addAccountExplicity() metodunu çağırarak hesap tipini kullanan ama işe yaramayacak bir hesap ekleyelim.

Bu metodunu çağırmanın en iyi yeri, uygulamanızın açılırken çağırılan onCreate() metodur. Aşağıdaki kod parçası nasıl yapılacağını göstermektedir:resim11resim12

Sync Adapter metadata dosyasını eklemek

Sync adapter bileşenimizi çatıya bağlamak için çatıyı, bileşeni anlatan ve ek bayrakları içeren bir metadata ile sunmalıyız. Bu metadata sync adapter’iniz için yarattığımız hesap tipini belirtir, uygulamamızla ilgili bir içerik sağlayıcıyı tanımlar, kullanıcı ara yüzünün sync adapter ile ilgili bir bölümünü kontrol eder ve diğer eş zamanlama bayraklarını belirtir. Bu metadatayı özel bir XML dosyası içinde /res/xml/ yoluna koyarız. Dosyaya istediğimiz ismi verebiliriz ancak genelde syncadapter.xml şeklinde adlandırılır.

Bu XML dosyası aşağıdaki özelliklere sahip tek bir XML parçası <sync-adapter> içerir:

android:contentAuthority: İçerik sağlayıcımız için yetkili URI. Eğer bir önceki konuda Aracı İçerik Sağlayıcı Yaratmak‘ta bir stub content provider oluşturduysak, uygulamamızın manifestine eklediğimiz <provider> elemanı içindeki attributeandroid:authorities’e atadığımız değeri kullanabilirizEğer içerik sağlayıcıdan sunucunuza sync adapter kullanarak veri aktarıyorsak, bu değer o veri için kullandığımız URI yetkilisiyle aynı değer olmalıdır.

android:accountType: Sync adapter çatısı için gerekli hesap tipidir. Bu değer, Doğrulayıcıyı Metadata Dosyasına Eklemek konusunda anlattığımız gibi yetkili metadata dosyasını oluşturduğumuzda atadığımız hesap tipi değeriyle aynı olmalıdır. Ayrıca bu değer, Çatı için Gereken Hesabı Eklemek bölümündeki kod parçasında ACCOUNT_TYPE’a atanan sabit değerdir.

Ayar değerleri

android:userVisible: Sync adapter’in hesap tipinin görünürlüğünü belirler. Varsayılan olarak, hesap tipiyle ilgili hesap simgesi ve yazısı sistemin ayarlar bölümünde Hesaplar kategorisinde görünür vaziyettedir yani sync adapter’imizi, uygulamamıza kolaylıkla ilişkilenebilen bir hesap tipi yoksa görünmez yapmamız gerekir. Hesap tipimizi görünmez yapsak dahi, kullanıcılarımızın sync adapter’imizi hâlâ ara yüzden kontrol etmelerini sağlayabiliriz.

android:supportsUploading:Buluta veri yüklememizi sağlar. Uygulamamız sadece veri indiriyorsa bunu false olarak atarız.

android:allowParallelSyncs: Sync adapter bileşenimizin birden fazla instance’ını aynı anda çalıştırmaya yarar. Eğer uygulamamız birden fazla kullanıcı hesabıyla çalışıyorsa ve kullanıcıların paralel olarak veri aktarmasını istiyorsak bunu kullanmalıyız. Eğer birden fazla veri transferi kullanmazsak bu bayrağın hiçbir etkisi yoktur.

android:isAlwaysSyncable: Sync adapter çatısına, sync adapteri belirlediğimiz zamanda çalıştırabileceğini gösterir. Eğer programatik olarak sync adapterimizin ne zaman çalışacağını kontrol etmek istiyorsak, bu bayrağı false olarak ayarlayıp, requestSync() metodunu çağırarak sync adapteri çalıştırırız.

Aşağıdaki örnek, uydurma bir hesap olup ve sadece indirme yapan bir sync adapter’e ait XML’i göstermektedir.resim13

Sync Adapter’i Manifest’te belirtmek

Sync adapter bileşenini uygulamamıza ekledikten sonra, bu bileşeni kullanan izinleri istememiz ve eklediğimiz bound service’i belirtmemiz gerekir.

Sync adapter bileşeni ağ ve cihaz arasında veri aktarımı yapan kodu çalıştırdığından, internete erişim izni istemeliyiz. Buna ek olarak, uygulamamız sync adapter ayarlarını okumak ve yazmak için izin istemelidir. Bu sayede sync adapteri programatik olarak diğer bileşenlerden kontrol edebiliriz. Ayrıca uygulamamızın Stub Authenticator Yaratmak konusunda yarattığımız yetkili bileşeninin kullanım iznini de istememiz gerekir.

Bu izinleri istemek için uygulamamızın manifestinde <manifest> elemanının altına aşağıdakileri eklememniz gerekir:

android.permission.INTERNET: Sync adapter kodunun İnternet’e erişmesine izin verir. Bu sayede cihazımıza sunucudan veri yükleme veya indirme yapabiliriz.

android.permission.READ_SYNC_SETTINGS: Uygulamamızın mevcut sync adapter ayarlarını okumasına izin verir. Örneğin, getIsSyncable() metodunu çağırmak için bu izini almamız gerekir.

android.permission.WRITE_SYNC_SETTINGS: Uygulamamızın sync adapter ayarlarını kontrol etmesine izin verir. addPeriodicSync() metodunu kullanarak periyodik sync adapter çalışması yapmak istiyorsak bu izni almalıyız. Bu izin requestSync() metodunu çağırmak için gerekli değildir.

android.permission.AUTHENTICATE_ACCOUNTS: Stub Authenticator Yaratmak konusunun içeriğinde yarattığımız yetkili bileşenini kullanmamıza izin verir.

Aşağıdaki kod parçası bu izinleri nasıl ekleyeceğinizi gösterir:resim14

Son olarak, çatının sync adapter ile iletişime geçmek de kullandığı bound Service’i belirtmek için aşağıdaki XML’i uygulamamızın manifestinde <application> elemanının altına ekleyelim:resim15

<intent-filter> elemanı, actionandroid.content.SyncAdapter intenti tarafından tetiklenen ve sync adapteri çalıştırmak için sistem tarafından yollanan bir filtre koyar. Bu filtre tetiklendiği zaman sistem yarattığımız bound service’i başlatır. Bu bound service örnekte SyncService olarak belirtilmiştir. android:exportes=”true” değeri uygulamamız harici işlemlerin Service’e erişmesini sağlar. android:process=”sync” değeri, sisteme Service’i sync isimli, genel paylaşılmış işlemin içinde çalışmasını söyler. Eğer uygulamamızda birden fazla sync adapter varsa bu işlemi paylaşabilirler, bu da aşırı yüklemeyi azaltır.

<meta-data> elemanı sync adapter’in metadatası olan XML dosyasının ismini verir. android:name değeri, bu metadatanın sync adapter çatısı için olduğunu belirtir. android:resource elemanı metadatanın ismini belirler.

Bir Sync Adapter’ı Çalıştırmak

Önceki konu içeriklerinde, veri aktarım kodunu kapsayan bir Sync Adapter bileşenini ve bu Sync Adapter’ı sistemimize bağlamak için gerekli diğer bileşenleri nasıl yaratacağımızı öğrendik. Bir Sync Adapter içeren uygulamayı yüklemek için her şeye sahibiz ancak gördüğümüz kodların hiç biri gerçekten bir Sync Adapter çalıştırmıyordu.

Sync Adapter’ımızı bir plana dayanarak ya da bir başka event’in direkt sonucu olarak çalıştırmayı deneyeceğiz. Örneğin, Sync Adapter’ımızı düzenli bir plana göre çalıştırmak istiyoruz, bu belirli bir zaman diliminden sonra da olabilir günün belirli zamanlarında da olabilir. Aynı zamanda bellekte saklanan veride herhangi bir değişiklik olduğunda da çalıştırmak isteyebiliriz. Sync Adapter’ımızı bir kullanıcı aksiyonunun direkt sonucu olarak çalıştırmaktan kaçınmalıyız çünkü böyle yaparak Sync Adapter uygulama çatısının planlama özelliğinden tam yararlanamamış oluruz. Örneğin, uygulamamıza bir yenileme düğmesi koymaktan kaçınmalıyız.

Çalışan Sync Adapter’ımız için aşağıdaki seçeneklere sahibiz:

  • Sunucu verisi değiştiğinde: Sync Adapter’ımızı sunucumuzdan gelen bir mesaja cevap olarak çalıştıralım, bu sayede sunucu tabanlı verinin değiştiğini göstermiş oluruz. Bu seçenek, sürekli sunucuyu yoklayarak harcayacağımız bataryayı ve performansı düşürerek veriyi güncellemem
  • Cihaz verisi değiştiğinde: Cihazımızdaki veri değiştiğinde Sync Adapter’ı çalıştıralım. Bu seçenek, değiştirilmiş veriyi cihazdan sunucuya yollamamızı ve bu sayede sunucunun her zaman güncel veriye sahip olduğunu güvence altına almamızı sağlar. Bu seçenek gerçekten içerik sağlayıcımızda veri tutuyorsanız doğrudan yazmamızı sağlar. Eğer aracı içerik sağlayıcı kullanıyorsak, veri değişikliklerini tespit etmek daha zor olabilir.
  • Sistem ağ mesajı yolladığında: Android sistem TCP/IP bağlantısını açık tutan bir ağ mesajı yolladığında Sync Adapter’ı çalıştıralım. Bu mesaj, ağ uygulama çatısının temel bir bölümüdür. Bu seçeneği kullanmak, Sync Adapter’ı otomatik çalıştırmanın bir yoludur.
  • Düzenli aralıklarla: Sync Adapter’ı belirlediğiniz bir zaman aralığı geçtiğinde ya da günün belli bir saatinde çalıştırın.
  • Gerekli olduğunda: Sync Adapter’ı bir kullanıcı aksiyonunda kullanalım. En iyi kullanıcı deneyimi için öncelikli olarak daha otomatik seçeneklere yönelmeliyiz. Bu sayede, batarya ve ağ kaynaklarını daha verimli kullanmış oluruz. 

Sync Adapter’ı sunucu verisi değiştiğinde çalıştırmak

Eğer uygulamamız sunucudan veri aktarımı yapıyorsa ve sunucu verisi aralıklarla değişiyorsa, Sync Adapter’ı veri değişikliklerine cevap olarak indirme işlemi için kullanabiliriz. Sync Adapter’ı çalıştırmak için sunucunun uygulamamızdaki aBroadcastReceiver’a bir mesaj göndermesini sağlayalım. Bu mesaja cevap olarak, ContentResolver.requestSync() ‘i çağırarak Sync Adapter çatısına Sync Adapter’ımızı çalıştırması için sinyal yollayalım.

Google Bulut Mesajlaşma (GCM), hem sunucu hem de cihaz bileşenlerini bu sistem mesajlaşması işini yapabilmesi için sağlar. Aktarımları daha güvenilir ve sürekli yoklama yönteminden daha verimli olarak yapmak istiyorsak GCM kullanarak tetikleyebiliriz. Yoklama Service’in her zaman aktif olmasını beklerken, GCM sadece mesaj geldiğinde aktif olan BroadcastReceiver’ı kullanır. Belirli aralıklarla yoklama batarya gücünü güncelleme olmasa bile kullanırken, GCM sadece gerekli olduğunda mesaj gönderir.

Aşağıdaki kod parçası requestSync()’in gelen bir GCM mesajına cevabını gösterir:resim17

Sync Adapter’ı içerik sağlayıcı verisi değiştiğinde çalıştırmak

Uygulamamız içerik sağlayıcımızda veri depoluyorsa ve sunucuyu içerik sağlayıcımız her güncellendiğinde güncellemek istiyorsak, uygulamamızı Sync Adapter’ı otomatik olarak güncellemesi için ayarlayabiliriz. Bunu yapmak için içerik sağlayıcımıza bir gözlemci bağlamamız gerekir. İçerik sağlayıcımızda veri değiştiği zaman içerik sağlayıcı uygulama çatısı gözlemciye haber verir. Gözlemci requestSync() metodunu çağırarak uygulama çatısına Sync Adapter’ı çalıştırmasını söyler.

İçerik sağlayıcmız için bir gözlemci yaratmak istiyorsak, ContentObserver sınıfını türeterek, onChange() metodunun her iki formunu da yazmamız gerekir. onChange() metodu içinde requestSync() metodunu çağırarak Sync Adapter’ınızı çalıştıralım.

Gözlemciyi kaydetmek için, registerContentObserver() metodunu çağırırken argüman olarak yollamamız gerekir. Bu çağırmada aynı zamanda izlemek istediğimiz veri için bir içerik URI de göndermemiz gerekir. İçerik sağlayıcı uygulama çatısı bu izleme URI’ı ile ContentResolver.insert() metodu gibi ContentResolver metodlarıyla yollanmış içerik URI’sını karşılaştırır. Eğer bir uyum varsa ofContentObserver.onChange() metodumuz çağrılır.

Aşağıdaki kod parçası bir tablo değiştiğinde requestSync() metodu çağıran bir ContentObserver nasıl tanımlanır onu gösteriyor:resim18resim19

Sync Adapter’ı bir ağ mesajından sonra çalıştırmak

Bir ağ bağlantısı mümkün olduğunda, Android sistem, TCP/IP bağlantısını açık tutmak için her saniye bir mesaj gönderir. Bu mesaj aynı zamanda her uygulamanın ContentResolver’ına gider. setSyncAutomatically() metodunu çağırarak, Sync Adapter’ı ContentResolver bu mesajı her aldığında çalışmasını sağlayabiliriz.

Sync Adapter’ımızı her ağ mesajı yollandığında çalıştırmak üzere planladığımızda, Sync Adapter’ın ağ uygun olduğunda hep çalışacak şekilde programladığımıza emin olmalıyız. Bu özelliği, her veri değişiminde veri aktarımına zorlamayacaksak ama verinin de belirli aralıklara güncel olduğundan emin olmak istediğimizde kullanırız. Benzer şekilde, bu seçeneği eğer Sync Adapter’ımız için sabit bir planlama istemiyorsak ama sıklıkla çalıştırmak istiyorsak kullanırız.

setSyncAutomatically(), addPeriodicSync() metodunu devre dışı bırakmadığı için, Sync Adapter’ıniz kısa zaman aralıklarında tekrar tekrar tetiklenebilir. Sync Adapter’ımızı belirli bir planda periyodik olarak çalıştırmak istiyorsak, setSyncAutomatically() metodunu devre dışı bırakmalıyız.

Aşağıdaki kod parçası, ContentResolver’ımızı Sync Adapter’ı bir ağ mesajına cevap olarak çalıştırmak istediğimizde nasıl ayarlamamız gerektiğini gösterecek:resim20

Sync Adapter’ı periyodik çalıştırın

Sync Adapter’ımızı çalışmalar arasında beklemek için belirli bir süre koyarak ya da günün belirli saatlerinde çalıştırarak periyodik olarak çalıştırabilirsiz. Sync Adapter’ımızı periyodik olarak çalıştırmak, kabaca sunucumuzdaki güncelleme aralığıyla eşleşecektir.

Benzer şekilde, Sync Adapter’ı gece de çalışacak hale getirirsek, sunucumuz bekleme durumundayken de cihazımıza veri yüklemesi yapabiliriz. Kullanıcıların çoğu, gece vakti cihazlarını güçte ya da fişte bırakırlar. Dolayısıyla bu vakitler uygun olur. Daha fazlası, Sync Adapter’ımız gibi diğer görevlerle aynı zamanda çalışıyor olmaz. Bu yaklaşımı seçsek dahi, her cihazın veri aktarımı için tetiklenme zamanının farklı olduğundan emin olmalıyız. Eğer tüm cihazlar Sync Adapter’ımızı aynı zamanda çalıştrırsa, sunucumuza ve veri ağlarına çok yüklenmiş oluruz.

Genelde periyodik çalıştırmalar, kullanıcılarımız anlık güncellemeler istemediğinde, düzenli güncellemeler istediklerinde işe yarar. Periyodik çalışmalar, aynı zamanda güncellenmiş verimizin uygunluğu ile daha küçük Sync Adapter çalıştırmalarımızın verimliliği arasındaki dengeyi cihaz kaynaklarını aşırı kullanmadan sağlar.

Sync Adapter’ı düzenli aralıklarlar çalıştırmak için addPeriodicSync() metodunu çağıralım. Bu, Sync Adapter’ımızı belirlenmiş bir zamana erişildiğinde çalıştırmak için planlar. Sync Adapter uygulama çatısı, diğer Sync Adapter uygulamalarına bağlı olduğu ve batarya verimliliğini en yükseğe çıkarmak için uğraştığı için belirlenmiş zaman birkaç saniye değişebilir. Aynı zamanda, uygulama çatısı eğer ağ uygun değilse Sync Adapter’ımızı çalıştırmayacaktır.

Şunu unutmayalım ki, addPeriodicSync() Sync Adapter’ı günün belirli saatlerinde çalıştırmaz. Sync Adapter’ı her gün kabaca aynı saatte çalıştırmak istiyorsak, tekrar eden bir alarmı tetikleyici olarak kullanmalıyız. Eğer setInexactRepeating() metodunu gün tetikleyicileri olarak kullanırsak, başlangıç saatini rastgele seçmeliyiz ki, bütün cihazlarda aynı olmasın.

addPeriodicSync() metodu setSyncAutomatically() metodunu devre dışı bırakmaz, dolayısıyla kısa bir zaman diliminde birden çok eş zamanlama yaşayabiliriz. Aynı zamanda sadece birkaç Sync Adapter kontrol bayrağı addPeriodicSync() metoduna eklenmesi için izin verilmiştir.

Aşağıdaki kod parçası Sync Adapter çalıştırmalarını nasıl planlamanız gerektiğini anlatır:resim21

Sync Adapter’ı ihtiyaç olduğunda çalıştırmak

Sync Adapter’ı bir kullanıcı isteğine cevap olarak çalıştırmak, çalışan bir Sync Adapter için en az tercih edilen stratejidir. Uygulama çatısı, Sync Adapter’leri plana göre çalıştırdığında, özel olarak batarya gücünü korumak için dizayn edilmiştir. Veri değiştiğinde cevap olarak eş zamanlama işi başlatmak batarya gücü verimliliğini etkiler, çünkü güç yeni veriyi almak için kullanılır.

Karşılaştırma yaptığımızda, kullanıcılara eş zamanlamayı ihtiyaç olduğunda yapmalarını sağlamak bunu kendi kendine yapabilmeleri demektir. Bu da ağ ve güç kullanımı adına verimsizlik demektir. Aynı zamanda ihtiyaç olduğunda eş zamanlama yapmak kullanıcılara veri değişimi olmadığında dahi eş zamanlama yapabilmeleri fırsatını verir. Genelde uygulamanız eş zamanlamayı tetiklemek için başka sinyaller kullanır ya da belirli aralıklara kendiliğinden olması için planlar.

Yine de ihtiyaç olduğunda Sync Adapter çalıştırmak istiyorsanız, Sync Adapter bayraklarını elle çalıştırma için ayarlayın ve ContentResolver.requestSynv() metodunu çağırın.

Aşağıdaki bayraklar bunun içindir:

  • SYNC_EXTRAS_MANUAL: Elle eşzamanlamaya zorlar. Sync Adapter uygulama çatısı, setSyncAutomatically() metodunun ayarladığı bayraklar gibi mevcut ayarları reddeder.
  • SYNC_EXTRAS_EXPEDITED: Eşzamanlamanın anında çalışması için zorlar. Bunu ayarlamazsanız, sistem bir eşzamanlama isteğini çalıştırmak için birkaç saniye bekleyebilir çünkü batarya kullanımını kısa zamanda çok gelen istekler için planlama yapmaya ayırır.

Aşağıdaki kod parçası requestSynv() metodunu bir düğmeye basıldığında çalıştırmak için ne yapmanız gerektiğini anlatır:resim22

 

Abdullah ATABAŞ

 

Kaynaklar

https://developer.android.com/training/sync-adapters/index.html

http://www.javaarm.cn/faces/display.xhtml;jsessionid=E0nVbhq5gUPE5EiMgc5GrKRy?tid=3152

https://gelecegiyazanlar.turkcell.com.tr/konu/android/egitim/android-401/sync-adapter-kullanarak-veri-tasimak

https://udinic.wordpress.com/2013/07/24/write-your-own-android-sync-adapter/

http://programmers.stackexchange.com/questions/219357/design-pattern-for-syncing-data-in-android

 

Yazar Hakkında

Yazar : Kadriye Kundakci

Yazar Hakkında :

Yazarın Tüm Yazıları İçin Tıklayınız

Yorumlar

Sitemizde En Çok Okunan İçerikler

ANDROİD TELEFONLARA ROOT ATMA
ANDROİD TELEFONLARA ROOT ATMARoot Ne demek ? Bir android cihazı root etmek telefonun
fragment
ANDROİD FRAGMENT YAPISI VE KULLANIMIFragmentler Activity içerisinde yer alan kullanıcı ara yüzleridir. Fragment
Asp.NET’de web servis hazırlama ve Android de kullanimi  Web Servis Nedir ? Web üzerinden HTTP protokolü ile hizmet
ANDROİD TELEFONLARDA KONFERANS GÖRÜŞME
ANDROİD TELEFONLARDA KONFERANS GÖRÜŞMEANDROİD TELEFONLARDA KONFERANS GÖRÜŞME   Konferans görüşme çok fazla bilinmeyen androidin

Sitemizde En Çok Yorumlanan İçerikler

Rating Bar Kullanımı
Rating Bar KullanımıAndroid’de yıldız şeklinde derecelendirme çubuğu olarak kullanılır. Kullanıcı sürükleme
Android Wear Emülatör Kurulumu
Android Wear Emülatör Kurulumu   Android studio da geliştireceğimiz uygulamaların kontrolunü yapmak için emülatör
Resim Galerisi Oluşturma
Resim Galerisi OluşturmaAndroid Programlama – Resim Galerisi Oluşturma Bu yazıda, bir galeri
SQLite Database Browser Kullanımı
SQLite Database Browser KullanımıSQLite Database Browser Kullanımı Merhaba arkadaşlar, Android uygulamaları geliştirirken uygulama üzerindeki

Son Yapılan Yorumlar

  • Kategoriler

  • Son Yazılar

  • Takvim

    Ekim 2017
    P S Ç P C C P
    « Kas    
     1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031  
  • Etiketler

  • Son Yorumlar

    • Arşivler

    • Meta