Not: WorkManager'ı öneririz. . Lütfen şu sayfaya bakın: arka plan işleme rehberini inceleyin.
Bu sınıftaki önceki derslerde, ayarlarınızı değiştirmek için senkronizasyon bağdaştırıcısı bileşenini nasıl Veri aktarımı kodunu ve başarılı bir şekilde işlem yapmanızı sağlayan ek bileşenlerin nasıl senkronizasyon adaptörünü sisteme takın. Artık Google Play'de uygulamanızı yüklemek için bir senkronizasyon bağdaştırıcısı içerir, ancak gördüğünüz kodların hiçbiri senkronizasyon bağdaştırıcısını çalıştırmaz.
Senkronizasyon bağdaştırıcınızı bir programa göre veya bazı özelliklerin dolaylı sonucu olarak çalıştırmayı denemeniz gerekir unutmayın. Örneğin, senkronizasyon bağdaştırıcınızın belirli bir zamanda veya günün belirli bir saatinde Senkronizasyonu otomatik olarak bağdaştırıcısını kontrol edin. senkronizasyon bağdaştırıcısını bir kullanıcı işleminin doğrudan sonucu olarak ayarlar, çünkü bunu yaptığınızda senkronizasyon bağdaştırıcısı çerçevesinin programlama kabiliyetinden kaynaklanır. Örneğin, yenileme düğmesi sunar.
Senkronizasyon bağdaştırıcınızı çalıştırmak için aşağıdaki seçeneklere sahipsiniz:
- Sunucu verileri değiştiğinde
- . Senkronizasyon bağdaştırıcısını, sunucudan gelen ve sunucu tabanlı verileri değişti. Bu seçenek, verileri sunucudan cihaza yenilemenize olanak tanır. performansı düşürmeden veya sunucuyu yoklayarak pil ömrünü boşa harcamadan kullanabilirsiniz.
- Cihaz verileri değiştiğinde
- . Cihazdaki veriler değiştiğinde senkronizasyon bağdaştırıcısı çalıştırın. Bu seçenek bir sunucuya aktarıldığından farklı olabilir ve özellikle de sunucu yapılandırmalı her zaman en güncel cihaz verilerine sahip olmasını sağlar. Bu seçeneği kullanarak depoluyorsanız bu işlemi yapmanızı öneririz. Saplama kullanıyorsanız veri değişikliklerini tespit etmek daha zor olabilir.
- Düzenli aralıklarla
- . Seçtiğiniz bir aralığın süresi dolduktan sonra bir senkronizasyon bağdaştırıcısı çalıştırın veya bağdaştırıcıyı belirli bir zamanda çalıştırın her gün çalışıyor.
- İstek üzerine
- . Kullanıcı işlemine yanıt olarak senkronizasyon bağdaştırıcısını çalıştırın. Ancak en iyi kullanıcıya öncelikle daha otomatik olan seçeneklerden birine güvenmeniz gerekir. Şunu kullanarak: otomatik seçeneklerle pil ve ağ kaynaklarından tasarruf edersiniz.
Bu dersin geri kalanında bu seçeneklerin her biri daha ayrıntılı olarak açıklanmaktadır.
Sunucu verileri değiştiğinde senkronizasyon bağdaştırıcısını çalıştırma
Uygulamanız bir sunucudan veri aktarıyor ve sunucu verileri sık sık değişiyorsa
veri değişikliklerine yanıt olarak indirme işlemi yapmak için bir senkronizasyon adaptörü. Senkronizasyon bağdaştırıcısını çalıştırmak için
Sunucu, uygulamanızdaki bir BroadcastReceiver
adresine özel bir mesaj gönderir.
Bu mesaja yanıt olarak, ContentResolver.requestSync()
senkronizasyon adaptörünü kullanmanız gerekir.
Google Cloud Messaging (GCM) hem
bu mesajlaşma sisteminin çalışması için gereken sunucu ve cihaz bileşenlerini içerir. Tetiklemek için GCM kullanma
aktarımları durum için yoklama sunucularından daha güvenilir ve verimlidir. Oy kullanırken
her zaman etkin olan bir Service
gerektirir. GCM,
BroadcastReceiver
Mesaj geldiğinde etkinleştirilir. Oy kullanırken
düzenli aralıklarla, kullanılabilir güncelleme olmasa bile pil gücünü kullanır, GCM yalnızca
mesaj gönderebilirsiniz.
Not: Tüm kullanıcılara bir yayın aracılığıyla senkronizasyon bağdaştırıcınızı tetiklemek için GCM'yi kullanırsanız uygulamanızın yüklü olduğu cihazlarda mesajınızı şu adrese giderek aldıklarını: aşağı yukarı aynı zamana denk geliyor. Bu durum, senkronizasyon bağdaştırıcınızın birden fazla örneğinin çalışmasına neden olabilir sunucu ve ağ yüküne neden olabilir. Yayında bu durumu önlemek için: senkronizasyon bağdaştırıcısının başlangıç tarihini bir süreliğine ertelemeyi benzersiz bir deneyim sunmalısınız.
Aşağıdaki kod snippet'i,
requestSync()
şuna yanıt olarak:
gelen GCM iletisi:
Kotlin
... // Constants // Content provider authority const val AUTHORITY = "com.example.android.datasync.provider" // Account type const val ACCOUNT_TYPE = "com.example.android.datasync" // Account const val ACCOUNT = "default_account" // Incoming Intent key for extended data const val KEY_SYNC_REQUEST = "com.example.android.datasync.KEY_SYNC_REQUEST" ... class GcmBroadcastReceiver : BroadcastReceiver() { ... override fun onReceive(context: Context, intent: Intent) { // Get a GCM object instance val gcm: GoogleCloudMessaging = GoogleCloudMessaging.getInstance(context) // Get the type of GCM message val messageType: String? = gcm.getMessageType(intent) /* * Test the message type and examine the message contents. * Since GCM is a general-purpose messaging system, you * may receive normal messages that don't require a sync * adapter run. * The following code tests for a a boolean flag indicating * that the message is requesting a transfer from the device. */ if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE == messageType && intent.getBooleanExtra(KEY_SYNC_REQUEST, false)) { /* * Signal the framework to run your sync adapter. Assume that * app initialization has already created the account. */ ContentResolver.requestSync(mAccount, AUTHORITY, null) ... } ... } ... }
Java
public class GcmBroadcastReceiver extends BroadcastReceiver { ... // Constants // Content provider authority public static final String AUTHORITY = "com.example.android.datasync.provider"; // Account type public static final String ACCOUNT_TYPE = "com.example.android.datasync"; // Account public static final String ACCOUNT = "default_account"; // Incoming Intent key for extended data public static final String KEY_SYNC_REQUEST = "com.example.android.datasync.KEY_SYNC_REQUEST"; ... @Override public void onReceive(Context context, Intent intent) { // Get a GCM object instance GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context); // Get the type of GCM message String messageType = gcm.getMessageType(intent); /* * Test the message type and examine the message contents. * Since GCM is a general-purpose messaging system, you * may receive normal messages that don't require a sync * adapter run. * The following code tests for a a boolean flag indicating * that the message is requesting a transfer from the device. */ if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType) && intent.getBooleanExtra(KEY_SYNC_REQUEST)) { /* * Signal the framework to run your sync adapter. Assume that * app initialization has already created the account. */ ContentResolver.requestSync(mAccount, AUTHORITY, null); ... } ... } ... }
İçerik sağlayıcı verileri değiştiğinde senkronizasyon bağdaştırıcısını çalıştırma
Uygulamanız bir içerik sağlayıcıda veri topluyorsa ve her seferinde sunucuyu güncellemek istiyorsanız
sağlayıcıyı güncellerseniz uygulamanızı senkronizasyon bağdaştırıcınızı otomatik olarak çalıştıracak şekilde ayarlayabilirsiniz. Yapılacaklar
İçerik sağlayıcı için bir gözlemci kaydedersiniz. İçerik sağlayıcınızdaki veriler
içerik sağlayıcı çerçevesi ise gözlemciyi çağırır. Gözlemcide
Çerçeveye çalışmasını bildirmek için requestSync()
senkronize edin.
Not: Bir saplama içerik sağlayıcısı kullanıyorsanız
içerik sağlayıcı ve onChange()
hiç çağrılmadı. Bu durumda
cihaz verileri. Bu mekanizma, müşterilerin telefon araması
Veriler değiştiğinde requestSync()
.
İçerik sağlayıcınız için bir gözlemci oluşturmak üzere sınıfı genişletin.
ContentObserver
ve her iki biçimini de uygulayın.
onChange()
yöntemini çağırın. İçinde
onChange()
, telefon et
Senkronizasyon bağdaştırıcısını başlatmak için requestSync()
.
Gözlemciyi kaydetmek için bunu bir çağrıda bağımsız değişken olarak iletin:
registerContentObserver()
İçinde
çağrısından sonra, izlemek istediğiniz veriler için bir içerik URI'si de iletmeniz gerekir. İçerik
provider çerçevesi, bu izleme URI'sini bağımsız değişken olarak iletilen içerik URI'leri ile
Sağlayıcınızı değiştiren ContentResolver
yöntem, ör.
ContentResolver.insert()
. Eşleşme varsa
ContentObserver.onChange()
uygulanması
çağrılır.
Aşağıdaki kod snippet'i, bir ContentObserver
özelliğini nasıl tanımlayacağınızı göstermektedir
bir tablo söz konusu olduğunda, requestSync()
değişiklikler:
Kotlin
// Constants // Content provider scheme const val SCHEME = "content://" // Content provider authority const val AUTHORITY = "com.example.android.datasync.provider" // Path for the content provider table const val TABLE_PATH = "data_table" ... class MainActivity : FragmentActivity() { ... // A content URI for the content provider's data table private lateinit var uri: Uri // A content resolver for accessing the provider private lateinit var mResolver: ContentResolver ... inner class TableObserver(...) : ContentObserver(...) { /* * Define a method that's called when data in the * observed content provider changes. * This method signature is provided for compatibility with * older platforms. */ override fun onChange(selfChange: Boolean) { /* * Invoke the method signature available as of * Android platform version 4.1, with a null URI. */ onChange(selfChange, null) } /* * Define a method that's called when data in the * observed content provider changes. */ override fun onChange(selfChange: Boolean, changeUri: Uri?) { /* * Ask the framework to run your sync adapter. * To maintain backward compatibility, assume that * changeUri is null. */ ContentResolver.requestSync(account, AUTHORITY, null) } ... } ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... // Get the content resolver object for your app mResolver = contentResolver // Construct a URI that points to the content provider data table uri = Uri.Builder() .scheme(SCHEME) .authority(AUTHORITY) .path(TABLE_PATH) .build() /* * Create a content observer object. * Its code does not mutate the provider, so set * selfChange to "false" */ val observer = TableObserver(false) /* * Register the observer for the data table. The table's path * and any of its subpaths trigger the observer. */ mResolver.registerContentObserver(uri, true, observer) ... } ... }
Java
public class MainActivity extends FragmentActivity { ... // Constants // Content provider scheme public static final String SCHEME = "content://"; // Content provider authority public static final String AUTHORITY = "com.example.android.datasync.provider"; // Path for the content provider table public static final String TABLE_PATH = "data_table"; // Account public static final String ACCOUNT = "default_account"; // Global variables // A content URI for the content provider's data table Uri uri; // A content resolver for accessing the provider ContentResolver mResolver; ... public class TableObserver extends ContentObserver { /* * Define a method that's called when data in the * observed content provider changes. * This method signature is provided for compatibility with * older platforms. */ @Override public void onChange(boolean selfChange) { /* * Invoke the method signature available as of * Android platform version 4.1, with a null URI. */ onChange(selfChange, null); } /* * Define a method that's called when data in the * observed content provider changes. */ @Override public void onChange(boolean selfChange, Uri changeUri) { /* * Ask the framework to run your sync adapter. * To maintain backward compatibility, assume that * changeUri is null. */ ContentResolver.requestSync(mAccount, AUTHORITY, null); } ... } ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... // Get the content resolver object for your app mResolver = getContentResolver(); // Construct a URI that points to the content provider data table uri = new Uri.Builder() .scheme(SCHEME) .authority(AUTHORITY) .path(TABLE_PATH) .build(); /* * Create a content observer object. * Its code does not mutate the provider, so set * selfChange to "false" */ TableObserver observer = new TableObserver(false); /* * Register the observer for the data table. The table's path * and any of its subpaths trigger the observer. */ mResolver.registerContentObserver(uri, true, observer); ... } ... }
Senkronizasyon bağdaştırıcısını düzenli olarak çalıştırma
Çalıştırmalar arasında beklenecek süre belirleyerek senkronizasyon bağdaştırıcınızı düzenli aralıklarla çalıştırabilirsiniz. veya günün belirli saatlerinde ya da her ikisinde birden yayınlayabilirsiniz. Senkronizasyon bağdaştırıcınızı çalıştırma düzenli aralıklarla, sunucunuzun güncelleme aralığını yaklaşık olarak eşleştirmenize olanak tanır.
Benzer şekilde, sunucunuz nispeten boştayken cihazdan veri yükleyebilirsiniz. senkronizasyon bağdaştırıcınızı gece çalışacak şekilde planlama. Çoğu kullanıcı kendi güçlerini açık ve fişe takılı bırakıyor Bu nedenle bu saat de genellikle uygun olur. Dahası, cihaz şu saatte başka görevler çalıştırmıyor: senkronizasyon bağdaştırıcınızla aynı anda çalışır. Ancak bu yaklaşımı benimserseniz, her cihaz biraz farklı bir zamanda veri aktarımını tetikler. Tüm cihazlar senkronizasyon bağdaştırıcısını aynı anda kullanmayı seçerseniz sunucu ve hücre sağlayıcı verilerinizde aşırı miktarda ağlar.
Periyodik çalıştırmalar genel olarak, kullanıcılarınız için anlık güncellemelere ihtiyaç duymayan ancak aynı zamanda düzenli olarak güncellenir. Belirli bir özelliğin kullanılabilirliğini dengelemek isterseniz, Cihazı aşırı kullanmayan daha küçük senkronizasyon bağdaştırıcısı çalıştırmalarının verimliliği sayesinde güncel veriler kaynaklar.
Senkronizasyon bağdaştırıcınızı düzenli aralıklarla çalıştırmak için
addPeriodicSync()
Bu,
senkronizasyon bağdaştırıcısını belirli bir süre geçtikten sonra çalışacak şekilde ayarlayın. Senkronizasyon bağdaştırıcısı çerçevesinin
diğer senkronizasyon bağdaştırıcısı yürütmelerini hesaba katması gerekir ve pil verimliliğini en üst düzeye çıkarmaya çalışırsa
geçen süre birkaç saniye farklılık gösterebilir. Ayrıca çerçeve, aşağıdaki durumlarda senkronizasyon bağdaştırıcınızı çalıştırmaz
ağı kullanılamıyor.
addPeriodicSync()
şunu yapmaz:
senkronizasyon bağdaştırıcısını günün belirli bir saatinde çalıştırmanız gerekir. Senkronizasyon bağdaştırıcınızı yaklaşık olarak
her gün aynı saatte çalışıyorsa tetikleyici olarak tekrarlanan bir alarmı kullanın. Tekrarlanan alarmlar daha fazla bilgi için açıklanmaktadır
bu AlarmManager
referans belgelerinde bulabilirsiniz. URL'yi
ayarlamak için setInexactRepeating()
yöntemini kullanın
günün saati tetikleyicileri varsa, bu tetikleyicileri kullanmak için başlangıç zamanını
senkronizasyon bağdaştırıcısının farklı cihazlarda çalıştığından emin olun.
addPeriodicSync()
yöntemi şunları yapmaz:
setSyncAutomatically()
devre dışı bırak,
Bu nedenle, nispeten kısa bir süre içinde birden fazla senkronizasyon çalıştırmanız olabilir. Ayrıca çok az sayıda
senkronizasyon bağdaştırıcısı kontrol bayraklarına yapılan çağrıda izin verilir
addPeriodicSync()
; önemli olan
izin verilmeyen konular,
addPeriodicSync()
.
Aşağıdaki kod snippet'i, düzenli senkronizasyon bağdaştırıcısı çalıştırmalarının nasıl planlanacağını gösterir:
Kotlin
// Content provider authority const val AUTHORITY = "com.example.android.datasync.provider" // Account const val ACCOUNT = "default_account" // Sync interval constants const val SECONDS_PER_MINUTE = 60L const val SYNC_INTERVAL_IN_MINUTES = 60L const val SYNC_INTERVAL = SYNC_INTERVAL_IN_MINUTES * SECONDS_PER_MINUTE ... class MainActivity : FragmentActivity() { ... // A content resolver for accessing the provider private lateinit var mResolver: ContentResolver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... // Get the content resolver for your app mResolver = contentResolver /* * Turn on periodic syncing */ ContentResolver.addPeriodicSync( mAccount, AUTHORITY, Bundle.EMPTY, SYNC_INTERVAL) ... } ... }
Java
public class MainActivity extends FragmentActivity { ... // Constants // Content provider authority public static final String AUTHORITY = "com.example.android.datasync.provider"; // Account public static final String ACCOUNT = "default_account"; // Sync interval constants public static final long SECONDS_PER_MINUTE = 60L; public static final long SYNC_INTERVAL_IN_MINUTES = 60L; public static final long SYNC_INTERVAL = SYNC_INTERVAL_IN_MINUTES * SECONDS_PER_MINUTE; // Global variables // A content resolver for accessing the provider ContentResolver mResolver; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... // Get the content resolver for your app mResolver = getContentResolver(); /* * Turn on periodic syncing */ ContentResolver.addPeriodicSync( mAccount, AUTHORITY, Bundle.EMPTY, SYNC_INTERVAL); ... } ... }
Senkronizasyon bağdaştırıcısını isteğe bağlı olarak çalıştırma
Senkronizasyon bağdaştırıcınızı bir kullanıcı isteğine yanıt olarak çalıştırmak, en az tercih edilen stratejidir bir senkronizasyon bağdaştırıcısı çalıştırmak için idealdir. Çerçeve, pil gücünü korumak için özel olarak tasarlanmıştır senkronizasyon bağdaştırıcılarını bir programa göre çalıştırır. Verilere göre senkronizasyon yapan seçenekler Güç Kaynağı yeni veri sağlamak için kullanıldığından değişiklikler pil gücünü etkili bir şekilde kullanır.
Buna karşılık, kullanıcıların istek üzerine senkronizasyon çalıştırmasına izin vermek, senkronizasyonun kendiliğinden çalıştığı anlamına gelir. ağın ve güç kaynaklarının verimsiz kullanımıdır. Ayrıca, istek üzerine senkronizasyon sağlamak, kullanıcıları verilerin değiştiğine dair bir kanıt olmasa bile senkronizasyon isteğinde bulunmalı ve , pil gücünün verimsiz bir şekilde kullanılmasıdır. Genel olarak, uygulamanız Kullanıcı girişi olmadan senkronizasyonu tetiklemek veya düzenli aralıklarla programlamak için diğer sinyalleri kullanma
Ancak senkronizasyon bağdaştırıcısını yine de istek üzerine çalıştırmak istiyorsanız senkronizasyon bağdaştırıcısı bayraklarını
manuel senkronizasyon bağdaştırıcısı çalıştırıp şunu ara:
ContentResolver.requestSync()
Aşağıdaki işaretlerle isteğe bağlı aktarımları çalıştırın:
-
SYNC_EXTRAS_MANUAL
- .
Manuel senkronizasyonu zorunlu kılar. Senkronizasyon bağdaştırıcısı çerçevesi mevcut ayarları yoksayar
örneğin
setSyncAutomatically()
tarafından ayarlanan bayrak gibi. -
SYNC_EXTRAS_EXPEDITED
- . Senkronizasyonu hemen başlamaya zorlar. Bunu ayarlamazsanız sistem, saniyeler içinde pil kullanımını optimize etmeye çalıştığı için, istek çalıştırılmadan önce kısa bir süre içinde çok sayıda istek planlamaktır.
Aşağıdaki kod snippet'i,
Bir düğmeye yanıt olarak requestSync()
tıklayın:
Kotlin
// Constants // Content provider authority val AUTHORITY = "com.example.android.datasync.provider" // Account type val ACCOUNT_TYPE = "com.example.android.datasync" // Account val ACCOUNT = "default_account" ... class MainActivity : FragmentActivity() { ... // Instance fields private lateinit var mAccount: Account ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... /* * Create the placeholder account. The code for CreateSyncAccount * is listed in the lesson Creating a Sync Adapter */ mAccount = createSyncAccount() ... } /** * Respond to a button click by calling requestSync(). This is an * asynchronous operation. * * This method is attached to the refresh button in the layout * XML file * * @param v The View associated with the method call, * in this case a Button */ fun onRefreshButtonClick(v: View) { // Pass the settings flags by inserting them in a bundle val settingsBundle = Bundle().apply { putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true) putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true) } /* * Request the sync for the default account, authority, and * manual sync settings */ ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle) }
Java
public class MainActivity extends FragmentActivity { ... // Constants // Content provider authority public static final String AUTHORITY = "com.example.android.datasync.provider"; // Account type public static final String ACCOUNT_TYPE = "com.example.android.datasync"; // Account public static final String ACCOUNT = "default_account"; // Instance fields Account mAccount; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... /* * Create the placeholder account. The code for CreateSyncAccount * is listed in the lesson Creating a Sync Adapter */ mAccount = CreateSyncAccount(this); ... } /** * Respond to a button click by calling requestSync(). This is an * asynchronous operation. * * This method is attached to the refresh button in the layout * XML file * * @param v The View associated with the method call, * in this case a Button */ public void onRefreshButtonClick(View v) { // Pass the settings flags by inserting them in a bundle Bundle settingsBundle = new Bundle(); settingsBundle.putBoolean( ContentResolver.SYNC_EXTRAS_MANUAL, true); settingsBundle.putBoolean( ContentResolver.SYNC_EXTRAS_EXPEDITED, true); /* * Request the sync for the default account, authority, and * manual sync settings */ ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle); }