Catatan: Kami merekomendasikan WorkManager sebagai solusi yang direkomendasikan untuk sebagian besar kasus penggunaan pemrosesan latar belakang. Harap lihat panduan pemrosesan di latar belakang untuk mempelajari solusi mana yang paling cocok untuk Anda.
Komponen adaptor sinkronisasi di aplikasi Anda merangkum kode untuk tugas yang mentransfer data antara perangkat dan server. Berdasarkan penjadwalan dan pemicu yang Anda berikan di aplikasi Anda, kerangka kerja adaptor sinkronisasi akan menjalankan kode dalam komponen adaptor sinkronisasi. Untuk menambahkan komponen adaptor sinkronisasi ke aplikasi, Anda perlu menambahkan bagian berikut:
- Class adaptor sinkronisasi.
- Class yang menggabungkan kode transfer data Anda dalam antarmuka yang kompatibel dengan adaptor sinkronisasi Google Workspace for Education.
-
Terikat
Service
. - Komponen yang memungkinkan framework adaptor sinkronisasi untuk menjalankan kode di adaptor sinkronisasi Anda .
- File metadata XML adaptor sinkronisasi.
- File yang berisi informasi tentang adaptor sinkronisasi Anda. Kerangka kerja membaca file ini ke cari tahu cara memuat dan menjadwalkan transfer data Anda.
- Deklarasi di manifes aplikasi.
- XML yang mendeklarasikan layanan terikat dan titik untuk menyinkronkan metadata khusus adaptor.
Tutorial ini menunjukkan cara mendefinisikan elemen ini.
Membuat class adaptor sinkronisasi
Di bagian pelajaran ini, Anda akan mempelajari cara membuat kelas adaptor sinkronisasi yang merangkum kode transfer data. Pembuatan kelas termasuk memperluas kelas dasar adaptor sinkronisasi, mendefinisikan konstruktor untuk class, dan mengimplementasikan metode yang digunakan untuk menentukan transfer data tugas klasifikasi.
Memperluas class adaptor sinkronisasi dasar
Untuk membuat komponen adaptor sinkronisasi, mulailah dengan memperluas
AbstractThreadedSyncAdapter
dan menulis konstruktornya. Gunakan
konstruktor untuk menjalankan tugas pengaturan setiap kali komponen adaptor sinkronisasi Anda dibuat dari
awal, sama seperti Anda menggunakan Activity.onCreate()
untuk menyiapkan
aktivitas Anda. Misalnya, jika aplikasi Anda menggunakan penyedia konten untuk menyimpan data, gunakan konstruktor
untuk mendapatkan instance ContentResolver
. Karena bentuk kedua dari
konstruktor ditambahkan di platform Android versi 3.0 untuk mendukung parallelSyncs
, Anda harus membuat dua bentuk konstruktor untuk mempertahankan kompatibilitas.
Catatan: Framework adaptor sinkronisasi dirancang untuk berfungsi dengan adaptor sinkronisasi komponen yang merupakan instance singleton. Pembuatan instance komponen adaptor sinkronisasi tercakup secara lebih detail pada bagian Ikat Adaptor Sinkronisasi ke Framework.
Contoh berikut menunjukkan cara mengimplementasikan
AbstractThreadedSyncAdapter
dan konstruktornya:
Kotlin
/** * Handle the transfer of data between a server and an * app, using the Android sync adapter framework. */ class SyncAdapter @JvmOverloads constructor( context: Context, autoInitialize: Boolean, /** * Using a default argument along with @JvmOverloads * generates constructor for both method signatures to maintain compatibility * with Android 3.0 and later platform versions */ allowParallelSyncs: Boolean = false, /* * If your app uses a content resolver, get an instance of it * from the incoming Context */ val mContentResolver: ContentResolver = context.contentResolver ) : AbstractThreadedSyncAdapter(context, autoInitialize, allowParallelSyncs) { ... }
Java
/** * Handle the transfer of data between a server and an * app, using the Android sync adapter framework. */ public class SyncAdapter extends AbstractThreadedSyncAdapter { ... // Global variables // Define a variable to contain a content resolver instance ContentResolver contentResolver; /** * Set up the sync adapter */ public SyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); /* * If your app uses a content resolver, get an instance of it * from the incoming Context */ contentResolver = context.getContentResolver(); } ... /** * Set up the sync adapter. This form of the * constructor maintains compatibility with Android 3.0 * and later platform versions */ public SyncAdapter( Context context, boolean autoInitialize, boolean allowParallelSyncs) { super(context, autoInitialize, allowParallelSyncs); /* * If your app uses a content resolver, get an instance of it * from the incoming Context */ contentResolver = context.getContentResolver(); ... }
Menambahkan kode transfer data
Komponen adaptor sinkronisasi tidak otomatis melakukan transfer data. Sebaliknya, hal itu
mengenkapsulasi kode transfer data Anda, sehingga framework adaptor sinkronisasi dapat menjalankan
transfer data di latar belakang, tanpa melibatkan aplikasi Anda. Saat framework sudah siap
untuk menyinkronkan data aplikasi Anda, ini akan memanggil implementasi metode tersebut
onPerformSync()
.
Untuk memfasilitasi transfer data dari kode aplikasi utama ke komponen adaptor sinkronisasi,
framework adaptor sinkronisasi memanggil
onPerformSync()
dengan
argumen berikut:
- Akun
-
Objek
Account
yang terkait dengan peristiwa yang memicu {i>sync<i} adaptor. Jika server Anda tidak menggunakan akun, Anda tidak perlu menggunakan informasi dalam objek ini. - Konten bonus
-
Bundle
yang berisi tanda yang dikirim oleh peristiwa yang memicu sinkronisasi {i>adaptor<i}. - Otoritas
- Otoritas penyedia konten dalam sistem. Aplikasi Anda harus memiliki akses ke penyedia ini. Biasanya, otoritas sesuai dengan penyedia konten di aplikasi Anda sendiri.
- Klien penyedia konten
-
ContentProviderClient
untuk penyedia konten yang ditunjukkan oleh {i>authority<i}.ContentProviderClient
adalah perangkat lunak publik ringan ke penyedia konten. Ia memiliki fungsi dasar yang sama denganContentResolver
. Jika Anda menggunakan penyedia konten untuk menyimpan data untuk aplikasi Anda, Anda dapat terhubung ke penyedia dengan objek ini. Jika tidak, Anda dapat mengabaikan anotasi. - Hasil sinkronisasi
-
Objek
SyncResult
yang Anda gunakan untuk mengirim informasi ke sinkronisasi framework adaptor.
Cuplikan berikut ini menunjukkan keseluruhan struktur dari
onPerformSync()
:
Kotlin
/* * Specify the code you want to run in the sync adapter. The entire * sync adapter runs in a background thread, so you don't have to set * up your own background processing. */ override fun onPerformSync( account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult ) { /* * Put the data transfer code here. */ }
Java
/* * Specify the code you want to run in the sync adapter. The entire * sync adapter runs in a background thread, so you don't have to set * up your own background processing. */ @Override public void onPerformSync( Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { /* * Put the data transfer code here. */ }
Walaupun implementasi
yang sebenarnya dari
onPerformSync()
dikhususkan untuk
persyaratan sinkronisasi data aplikasi Anda dan protokol
koneksi server, ada beberapa
tugas-tugas umum yang harus dilakukan penerapan Anda:
- Menghubungkan ke server
- Meskipun Anda dapat berasumsi bahwa jaringan tersedia saat transfer data dimulai, kerangka kerja adaptor sinkronisasi tidak otomatis terhubung ke server.
- Mendownload dan mengupload data
- Adaptor sinkronisasi tidak mengotomatiskan tugas transfer data apa pun. Jika Anda ingin mengunduh data dari server dan menyimpannya di penyedia konten, Anda harus menyediakan kode meminta data, mengunduhnya, dan memasukkannya ke dalam penyedia. Demikian pula, jika Anda ingin mengirim data ke server, Anda harus membacanya dari file, {i>database<i}, atau penyedia, dan permintaan upload yang diperlukan. Anda juga harus menangani kesalahan jaringan yang terjadi saat Anda transfer data berjalan.
- Menangani konflik data atau menentukan status data
- Adaptor sinkronisasi tidak secara otomatis menangani konflik antara data di server dan data di perangkat. Selain itu, NTFS tidak secara otomatis mendeteksi apakah data di server lebih baru dari data pada perangkat, atau sebaliknya. Sebagai gantinya, Anda harus menyediakan algoritma Anda sendiri untuk dalam menangani situasi ini.
- Pembersihan.
- Selalu tutup koneksi ke server dan bersihkan file sementara dan {i>cache<i} di akhir transfer data Anda.
Catatan: Framework adaptor sinkronisasi berjalan
onPerformSync()
pada
latar belakang, sehingga Anda tidak perlu
menyiapkan pemrosesan latar belakang sendiri.
Selain tugas yang terkait dengan sinkronisasi, Anda juga harus mencoba menggabungkan
tugas terkait jaringan
dan menambahkannya ke
onPerformSync()
.
Dengan memusatkan semua tugas jaringan Anda dalam metode ini, Anda menghemat daya baterai yang
yang diperlukan untuk memulai dan
menghentikan antarmuka jaringan. Untuk mempelajari lebih lanjut cara meningkatkan akses jaringan
efisien, lihat kelas pelatihan Mentransfer Data Tanpa Menguras Baterai, yang menjelaskan beberapa akses jaringan
tugas yang dapat Anda sertakan
dalam kode transfer data Anda.
Mengaitkan adaptor sinkronisasi ke framework
Anda sekarang memiliki kode transfer data yang dienkapsulasi dalam komponen adaptor sinkronisasi, tetapi Anda memiliki
untuk memberi framework akses ke kode Anda. Untuk melakukan ini, Anda
perlu membuat
Service
yang meneruskan objek binder Android khusus dari adaptor sinkronisasi
ke dalam kerangka kerja. Dengan objek binder ini, framework dapat memanggil metode
Metode onPerformSync()
dan
meneruskan data ke sana.
Buat instance komponen adaptor sinkronisasi sebagai singleton di
Metode onCreate()
layanan. Dengan membuat instance
komponen di onCreate()
, Anda akan menunda
membuatnya hingga layanan dimulai, yang terjadi saat framework pertama kali mencoba menjalankan
untuk mentransfer data. Anda perlu membuat instance komponen dengan cara yang aman untuk thread, jika sinkronisasi
kerangka kerja adaptor mengantrekan beberapa eksekusi
adaptor sinkronisasi Anda sebagai respons terhadap pemicu atau
penjadwalan.
Misalnya, cuplikan berikut menunjukkan cara membuat class yang menerapkan atribut
mengikat Service
, membuat instance komponen adaptor sinkronisasi, dan mendapatkan
Objek binder Android:
Kotlin
package com.example.android.syncadapter /** * Define a Service that returns an [android.os.IBinder] for the * sync adapter class, allowing the sync adapter framework to call * onPerformSync(). */ class SyncService : Service() { /* * Instantiate the sync adapter object. */ override fun onCreate() { /* * Create the sync adapter as a singleton. * Set the sync adapter as syncable * Disallow parallel syncs */ synchronized(sSyncAdapterLock) { sSyncAdapter = sSyncAdapter ?: SyncAdapter(applicationContext, true) } } /** * Return an object that allows the system to invoke * the sync adapter. * */ override fun onBind(intent: Intent): IBinder { /* * Get the object that allows external processes * to call onPerformSync(). The object is created * in the base class code when the SyncAdapter * constructors call super() * * We should never be in a position where this is called before * onCreate() so the exception should never be thrown */ return sSyncAdapter?.syncAdapterBinder ?: throw IllegalStateException() } companion object { // Storage for an instance of the sync adapter private var sSyncAdapter: SyncAdapter? = null // Object to use as a thread-safe lock private val sSyncAdapterLock = Any() } }
Java
package com.example.android.syncadapter; /** * Define a Service that returns an <code><a href="/reference/android/os/IBinder.html">IBinder</a></code> for the * sync adapter class, allowing the sync adapter framework to call * onPerformSync(). */ public class SyncService extends Service { // Storage for an instance of the sync adapter private static SyncAdapter sSyncAdapter = null; // Object to use as a thread-safe lock private static final Object sSyncAdapterLock = new Object(); /* * Instantiate the sync adapter object. */ @Override public void onCreate() { /* * Create the sync adapter as a singleton. * Set the sync adapter as syncable * Disallow parallel syncs */ synchronized (sSyncAdapterLock) { if (sSyncAdapter == null) { sSyncAdapter = new SyncAdapter(getApplicationContext(), true); } } } /** * Return an object that allows the system to invoke * the sync adapter. * */ @Override public IBinder onBind(Intent intent) { /* * Get the object that allows external processes * to call onPerformSync(). The object is created * in the base class code when the SyncAdapter * constructors call super() */ return sSyncAdapter.getSyncAdapterBinder(); } }
Catatan: Untuk melihat contoh layanan terikat yang lebih mendetail untuk adaptor sinkronisasi, lihat aplikasi contoh.
Menambahkan akun yang diperlukan oleh framework
Framework adaptor sinkronisasi mengharuskan setiap adaptor sinkronisasi memiliki jenis akun. Anda menyatakan
nilai jenis akun di bagian
Tambahkan File Metadata Authenticator. Sekarang Anda harus menyiapkan jenis akun ini di
Android. Untuk menyiapkan jenis akun, tambahkan akun placeholder yang menggunakan jenis akun tersebut
dengan memanggil addAccountExplicitly()
.
Tempat terbaik untuk memanggil metode ini adalah di
Metode onCreate()
dari aplikasi Anda
membuka aktivitas. Cuplikan kode berikut menunjukkan cara melakukan hal ini:
Kotlin
... // Constants // The authority for the sync adapter's content provider const val AUTHORITY = "com.example.android.datasync.provider" // An account type, in the form of a domain name const val ACCOUNT_TYPE = "example.com" // The account name const val ACCOUNT = "placeholderaccount" ... class MainActivity : FragmentActivity() { // Instance fields private lateinit var mAccount: Account ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... // Create the placeholder account mAccount = createSyncAccount() ... } ... /** * Create a new placeholder account for the sync adapter */ private fun createSyncAccount(): Account { val accountManager = getSystemService(Context.ACCOUNT_SERVICE) as AccountManager return Account(ACCOUNT, ACCOUNT_TYPE).also { newAccount -> /* * Add the account and account type, no password or user data * If successful, return the Account object, otherwise report an error. */ if (accountManager.addAccountExplicitly(newAccount, null, null)) { /* * If you don't set android:syncable="true" in * in your <provider> element in the manifest, * then call context.setIsSyncable(account, AUTHORITY, 1) * here. */ } else { /* * The account exists or some other error occurred. Log this, report it, * or handle it internally. */ } } } ... }
Java
public class MainActivity extends FragmentActivity { ... ... // Constants // The authority for the sync adapter's content provider public static final String AUTHORITY = "com.example.android.datasync.provider"; // An account type, in the form of a domain name public static final String ACCOUNT_TYPE = "example.com"; // The account name public static final String ACCOUNT = "placeholderaccount"; // Instance fields Account mAccount; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... // Create the placeholder account mAccount = CreateSyncAccount(this); ... } ... /** * Create a new placeholder account for the sync adapter * * @param context The application context */ public static Account CreateSyncAccount(Context context) { // Create the account type and default account Account newAccount = new Account( ACCOUNT, ACCOUNT_TYPE); // Get an instance of the Android account manager AccountManager accountManager = (AccountManager) context.getSystemService( ACCOUNT_SERVICE); /* * Add the account and account type, no password or user data * If successful, return the Account object, otherwise report an error. */ if (accountManager.addAccountExplicitly(newAccount, null, null)) { /* * If you don't set android:syncable="true" in * in your <provider> element in the manifest, * then call context.setIsSyncable(account, AUTHORITY, 1) * here. */ } else { /* * The account exists or some other error occurred. Log this, report it, * or handle it internally. */ } } ... }
Menambahkan file metadata adaptor sinkronisasi
Untuk menyambungkan komponen adaptor sinkronisasi ke dalam framework, Anda harus menyediakan framework
dengan metadata yang menjelaskan komponen dan memberikan tanda tambahan. {i>Metadata<i} menentukan
jenis akun yang telah Anda buat untuk adaptor sinkronisasi, mendeklarasikan otoritas penyedia konten
yang terkait dengan aplikasi Anda, mengontrol bagian
antarmuka pengguna sistem yang terkait dengan adaptor sinkronisasi,
dan mendeklarasikan tanda lain terkait sinkronisasi. Deklarasikan metadata ini dalam file XML khusus yang disimpan di
direktori /res/xml/
di project aplikasi Anda. Anda dapat memberikan
nama apa pun untuk file,
meskipun biasanya disebut syncadapter.xml
.
File XML ini berisi satu elemen XML <sync-adapter>
yang memiliki
atribut berikut:
android:contentAuthority
-
Otoritas URI untuk penyedia konten Anda. Jika Anda membuat penyedia konten stub untuk
aplikasi Anda pada pelajaran sebelumnya Membuat Penyedia Konten Stub, gunakan nilai yang Anda tentukan untuk
atribut
android:authorities
di elemen<provider>
yang Anda tambahkan ke manifes aplikasi. Atribut ini dijelaskan secara lebih detail dalam bagian Deklarasikan Penyedia dalam Manifes.
Jika Anda mentransfer data dari penyedia konten ke server dengan adaptor sinkronisasi, harus sama dengan otoritas URI konten yang Anda gunakan untuk data tersebut. Nilai ini juga merupakan salah satu otoritas yang Anda tentukan dalamandroid:authorities
elemen<provider>
yang mendeklarasikan penyedia dalam manifes aplikasi Anda. android:accountType
-
Jenis akun yang diperlukan oleh framework adaptor sinkronisasi. Nilainya harus sama
sebagai nilai jenis akun yang Anda berikan saat membuat file metadata otentikator, sebagai
dijelaskan di bagian Menambahkan File Metadata Authenticator. Ini juga merupakan nilai yang Anda tentukan untuk
konstanta
ACCOUNT_TYPE
dalam cuplikan kode di bagian Tambahkan Akun yang Diwajibkan oleh Framework. - Atribut setelan
-
-
android:userVisible
- Menyetel visibilitas jenis akun adaptor sinkronisasi. Secara default, ikon dan label akun yang terkait dengan jenis akun dapat dilihat di bagian Akun di aplikasi Setelan sistem, jadi Anda harus membuat sinkronisasi adaptor tak terlihat kecuali Anda memiliki jenis akun atau domain yang mudah dikaitkan dengan aplikasi Anda. Jika Anda membuat jenis akun Anda tidak terlihat, Anda tetap dapat mengizinkan pengguna untuk mengontrol adaptor sinkronisasi Anda dengan antarmuka pengguna di salah satu aktivitas aplikasi Anda.
-
android:supportsUploading
-
Memungkinkan Anda mengupload data ke cloud. Tetapkan parameter ini ke
false
jika aplikasi Anda saja mengunduh data. -
android:allowParallelSyncs
- Memungkinkan beberapa instance komponen adaptor sinkronisasi Anda dijalankan di waktu yang sama. Gunakan ini jika aplikasi Anda mendukung beberapa akun pengguna dan Anda ingin mengizinkan lebih dari satu akun untuk mentransfer data secara paralel. Flag ini tidak berpengaruh jika Anda tidak pernah menjalankan beberapa transfer data.
-
android:isAlwaysSyncable
-
Menunjukkan pada framework adaptor sinkronisasi bahwa framework tersebut dapat menjalankan adaptor sinkronisasi Anda kapan saja
waktu yang Anda tentukan. Jika Anda ingin mengontrol waktu sinkronisasi secara terprogram
adaptor dapat berjalan, menyetel flag ini ke
false
, lalu memanggilrequestSync()
untuk menjalankan {i>synchronize<i}. Untuk mempelajari lebih lanjut cara menjalankan adaptor sinkronisasi, lihat tutorial Menjalankan Adaptor Sinkronisasi
-
Contoh berikut menunjukkan XML untuk adaptor sinkronisasi yang menggunakan akun placeholder tunggal dan hanya melakukan download.
<?xml version="1.0" encoding="utf-8"?> <sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:contentAuthority="com.example.android.datasync.provider" android:accountType="com.android.example.datasync" android:userVisible="false" android:supportsUploading="false" android:allowParallelSyncs="false" android:isAlwaysSyncable="true"/>
Mendeklarasikan adaptor sinkronisasi dalam manifes
Setelah menambahkan komponen adaptor sinkronisasi ke aplikasi, Anda harus meminta izin
yang terkait dengan penggunaan komponen, dan Anda harus mendeklarasikan Service
terikat
yang telah ditambahkan.
Karena komponen adaptor sinkronisasi menjalankan kode yang mentransfer data antara jaringan dan perangkat seluler, Anda perlu meminta izin untuk mengakses Internet. Selain itu, aplikasi Anda membutuhkan untuk meminta izin membaca dan menulis setelan adaptor sinkronisasi, sehingga Anda dapat mengontrol adaptor secara terprogram dari komponen lain dalam aplikasi Anda. Anda juga perlu meminta izin khusus yang memungkinkan aplikasi Anda menggunakan komponen otentikator yang Anda buat dalam pelajaran Membuat Pengautentikasi Stub.
Untuk meminta izin ini, tambahkan hal berikut ke manifes aplikasi sebagai elemen turunan dari
<manifest>
:
-
android.permission.INTERNET
- Memungkinkan kode adaptor sinkronisasi mengakses Internet sehingga dapat mendownload atau mengupload data dari perangkat ke server. Anda tidak perlu menambahkan izin ini lagi jika Anda memintanya sebelumnya.
-
android.permission.READ_SYNC_SETTINGS
-
Memungkinkan aplikasi Anda membaca setelan adaptor sinkronisasi saat ini. Misalnya, Anda memerlukan
izin untuk memanggil
getIsSyncable()
. -
android.permission.WRITE_SYNC_SETTINGS
-
Memungkinkan aplikasi Anda mengontrol setelan adaptor sinkronisasi. Anda memerlukan izin akses ini untuk
menyetel adaptor sinkronisasi berkala yang berjalan menggunakan
addPeriodicSync()
. Izin ini tidak diperlukan untuk memanggilrequestSync()
. Untuk mempelajari lebih lanjut tentang menjalankan adaptor sinkronisasi, lihat Menjalankan Adaptor Sinkronisasi.
Cuplikan berikut menunjukkan cara menambahkan izin:
<manifest> ... <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/> <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/> ... </manifest>
Terakhir, untuk mendeklarasikan Service
terikat yang digunakan framework untuk
berinteraksi dengan adaptor sinkronisasi, tambahkan XML berikut ke manifes aplikasi Anda sebagai elemen turunan
dari <application>
:
<service android:name="com.example.android.datasync.SyncService" android:exported="false" android:process=":sync"> <intent-filter> <action android:name="android.content.SyncAdapter"/> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" /> </service>
Tujuan
<intent-filter>
akan menyiapkan filter yang dipicu oleh tindakan intent
android.content.SyncAdapter
, yang dikirim oleh sistem untuk menjalankan adaptor sinkronisasi. Kapan filter
dipicu, sistem akan memulai layanan terikat yang Anda buat, dalam contoh ini
SyncService
. Atribut
android:exported="false"
hanya memungkinkan aplikasi dan sistem untuk mengakses
Service
. Atribut
android:process=":sync"
memberi tahu sistem untuk menjalankan Service
dalam proses bersama global bernama
sync
. Jika Anda memiliki beberapa adaptor
sinkronisasi di aplikasi Anda, mereka dapat berbagi proses ini,
yang mengurangi {i>overhead<i}.
Tujuan
<meta-data>
menyediakan nama file XML metadata adaptor sinkronisasi yang Anda buat sebelumnya.
Tujuan
android:name
menunjukkan bahwa metadata ini untuk framework adaptor sinkronisasi. Tujuan
android:resource
menetapkan nama file metadata.
Sekarang Anda memiliki semua komponen untuk adaptor sinkronisasi Anda. Pelajaran berikutnya menunjukkan cara memberi tahu framework adaptor sinkronisasi untuk menjalankan adaptor sinkronisasi, baik sebagai respons terhadap suatu peristiwa dengan jadwal rutin.