ملاحظة: ننصح باستخدام WorkManager كحلّ مقترَح لمعظم حالات استخدام المعالجة في الخلفية. يُرجى الرجوع إلى دليل المعالجة في الخلفية لمعرفة الحلّ الأنسب لك.
يعمل مكوّن محوِّل المزامنة في تطبيقك على تضمين الرمز للمهام التي تنقل البيانات بين الجهاز والخادم. استنادًا إلى الجدولة والعوامل المُشغِّلة التي تقدّمها في تطبيقك، يُشغِّل إطار عمل محوّل المزامنة الرمز في مكوّن محوّل المزامنة. لإضافة مكوِّن محوِّل المزامنة إلى تطبيقك، يجب إضافة الأجزاء التالية:
- فئة محوِّل المزامنة.
- فئة تتضمن رمز نقل البيانات في واجهة متوافقة مع إطار عمل محوّل المزامنة.
-
يجب أن تكون القيمة مرتبطة بـ
Service
. - مكوِّن يسمح لإطار عمل محوّل المزامنة بتشغيل الرمز في فئة محوِّل المزامنة.
- ملف البيانات الوصفية بتنسيق XML لمحوّل المزامنة.
- ملف يحتوي على معلومات عن محوّل المزامنة. يقرأ إطار العمل هذا الملف لمعرفة كيفية تحميل عملية نقل البيانات وجدولتها.
- نماذج البيان في بيان التطبيق
- ملف XML الذي يوضِّح الخدمة المرتبطة ويوجّه البيانات الوصفية الخاصة بالمحوّل.
يوضح لك هذا الدرس كيفية تحديد هذه العناصر.
إنشاء فئة لمحوّل المزامنة
في هذا الجزء من الدرس، ستتعلّم طريقة إنشاء فئة محوّل المزامنة التي تتضمن رمز نقل البيانات. ويتضمّن إنشاء الفئة تمديد الفئة الأساسية لمحوّل المزامنة، وتحديد البنات الأساسية للفئة، وتطبيق الطريقة التي تحدّد من خلالها مهام نقل البيانات.
تمديد فئة محوِّل المزامنة الأساسية
لإنشاء مكوِّن محوِّل المزامنة، ابدأ بتوسيع
AbstractThreadedSyncAdapter
وكتابة التركيبات البرمجية له. يمكنك استخدام
البُنى الإنشائية لتشغيل مهام الإعداد في كل مرة يتم فيها إنشاء مكوّن محوِّل المزامنة من
البداية، تمامًا مثلما تستخدم Activity.onCreate()
لإعداد
نشاط. على سبيل المثال، إذا كان تطبيقك يستخدم موفّر محتوى لتخزين البيانات، استخدِم المنشئات
للحصول على مثيل ContentResolver
. بما أنّه تمت إضافة نموذج ثانٍ من
الدالة الإنشائية إلى الإصدار 3.0 من نظام Android الأساسي لإتاحة الوسيطة parallelSyncs
،
عليك إنشاء شكلَين من الدالة الإنشائية للحفاظ على التوافق.
ملاحظة: تم تصميم إطار عمل محوِّل المزامنة للعمل مع مكوّنات محوِّلات المزامنة التي تمثّل مثيلات فردية. ويتضمّن القسم ربط محوِّل المزامنة بإطار العمل مزيدًا من التفاصيل عن إنشاء مثيل مكوّن محوِّل المزامنة.
يوضِّح لك المثال التالي كيفية تطبيق السمة AbstractThreadedSyncAdapter
ووجهات إنشاءها:
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(); ... }
إضافة رمز نقل البيانات
لا يجري مكوّن محوّل المزامنة نقل البيانات تلقائيًا. وبدلاً من ذلك، يتم تضمين رمز نقل البيانات لكي يتمكّن إطار عمل محوّل المزامنة من تنفيذ عملية نقل البيانات في الخلفية بدون أي تدخّل من تطبيقك. وعندما يكون إطار العمل جاهزًا لمزامنة بيانات تطبيقك، يستدعي تنفيذ الطريقة onPerformSync()
.
لتسهيل نقل البيانات من رمز التطبيق الرئيسي إلى مكوّن محوِّل المزامنة،
يطلب إطار عمل محوِّل المزامنة
onPerformSync()
مع
الوسيطات التالية:
- الحساب
-
عنصر
Account
مرتبط بالحدث الذي أدّى إلى تشغيل محوّل المزامنة. إذا كان خادمك لا يستخدم الحسابات، لن تحتاج إلى استخدام المعلومات في هذا الكائن. - محتوى إضافي
-
Bundle
يحتوي على علامات تم إرسالها من خلال الحدث الذي أدّى إلى تشغيل محوِّل المزامنة. - الجهة
- تفويض موفّر المحتوى في النظام يجب أن يتمكن تطبيقك من الوصول إلى مقدّم الخدمة هذا. عادةً ما تتوافق السلطة مع موفّر المحتوى في تطبيقك.
- عميل موفّر المحتوى
-
العلامة
ContentProviderClient
لموفّر المحتوى المُشار إليها من خلال وسيطة المرجع.ContentProviderClient
هي واجهة بسيطة وعامة لموفّر محتوى. ويشتمل على الوظائف الأساسية نفسها التي يتضمّنهاContentResolver
. إذا كنت تستخدم موفّر محتوى لتخزين بيانات تطبيقك، يمكنك الاتصال بالموفّر باستخدام هذا الكائن. وبخلاف ذلك، يمكنك تجاهله. - نتيجة المزامنة
-
عنصر
SyncResult
تستخدمه لإرسال المعلومات إلى إطار عمل محوّل المزامنة.
يعرض المقتطف التالي البنية العامة للسمة 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. */ }
مع أنّ التنفيذ الفعلي لـ onPerformSync()
يقتصر على متطلبات مزامنة البيانات في تطبيقك وبروتوكولات الاتصال بالخادم، هناك بعض المهام العامة التي يجب أن تؤديها عملية التنفيذ:
- الاتصال بخادم
- علمًا أنّه يمكنك افتراض أنّ الشبكة متاحة عند بدء عملية نقل البيانات، لا يتصل إطار عمل محوّل المزامنة تلقائيًا بأي خادم.
- تنزيل البيانات وتحميلها
- لا يشغِّل محوّل المزامنة أي مهام لنقل البيانات تلقائيًا. إذا أردت تنزيل البيانات من خادم وتخزينها في موفّر محتوى، عليك تقديم الرمز الذي يطلب البيانات، وتنزيلها، ثم إدراجها في الموفِّر. وبالمثل، إذا أردت إرسال البيانات إلى خادم، عليك قراءتها من ملف أو قاعدة بيانات أو موفّر، ثم إرسال طلب التحميل اللازم. عليك أيضًا معالجة أخطاء الشبكة التي تحدث أثناء عملية نقل البيانات.
- التعامل مع تضاربات البيانات أو تحديد مدى حداثة البيانات
- لا يتعامل محوِّل المزامنة تلقائيًا مع التعارضات بين البيانات على الخادم والبيانات على الجهاز. ولا يرصد تلقائيًا ما إذا كانت البيانات على الخادم أحدث من البيانات على الجهاز أو العكس. بدلاً من ذلك، يجب توفير خوارزمياتك الخاصة للتعامل مع هذا الموقف.
- إخلاء مساحة تخزين
- عليك دائمًا إغلاق الاتصالات بخادم وتنظيف الملفات المؤقتة وذاكرات التخزين المؤقت عند انتهاء عملية نقل البيانات.
ملاحظة: يعمل إطار عمل محوّل المزامنة على تشغيل onPerformSync()
على سلسلة محادثات في الخلفية، لذلك لن تحتاج إلى إعداد إعدادات المعالجة في الخلفية بنفسك.
بالإضافة إلى المهام ذات الصلة بالمزامنة، يجب محاولة دمج المهام العادية المرتبطة بالشبكة وإضافتها إلى
"onPerformSync()
".
ومن خلال تركيز جميع مهام الشبكة على هذه الطريقة، يتم توفير طاقة البطارية اللازمة
لبدء تشغيل واجهات الشبكة وإيقافها. لمعرفة مزيد من المعلومات حول تعزيز كفاءة الوصول إلى الشبكة، راجِع فئة التدريب نقل البيانات بدون استنزاف البطارية التي تصف العديد من مهام الوصول إلى الشبكة التي يمكنك تضمينها في رمز نقل البيانات.
ربط محوِّل المزامنة بإطار العمل
لديك الآن رمز نقل البيانات مضمَّن في مكوّن محوِّل المزامنة، ولكن عليك منح إطار العمل إمكانية الوصول إلى الرمز. لإجراء ذلك، عليك إنشاء
Service
مرتبط يمرّر كائن مجلد Android خاصًا من مكوّن محوِّل المزامنة
إلى إطار العمل. باستخدام كائن الصنف Binder هذا، يمكن لإطار العمل استدعاء طريقة onPerformSync()
وتمرير البيانات إليها.
إنشاء مثيل لمكوِّن محوِّل المزامنة كوحدة مفردة في طريقة
onCreate()
للخدمة. من خلال إنشاء
مثيل للمكوِّن في onCreate()
، يمكنك تأجيل
إنشائه حتى بدء الخدمة، ويحدث ذلك عندما يحاول إطار العمل
نقل البيانات للمرة الأولى. تحتاج إلى إنشاء مثيل للمكوِّن بطريقة آمنة لسلسلة المحادثات، إذا كان إطار عمل محوِّل المزامنة
يضع عمليات تنفيذ متعددة لمحوِّل المزامنة استجابةً للعوامل المُشغِّلة أو
الجدولة.
على سبيل المثال، يوضّح لك المقتطف التالي طريقة إنشاء فئة تطبّق Service
المرتبط، وتنشئ مثيلاً لمكوِّن محوِّل المزامنة، وتحصل على كائن برنامج الربط على 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(); } }
ملاحظة: للاطّلاع على مثال أكثر تفصيلاً على خدمة مرتبطة لمحوّل مزامنة، يُرجى الاطّلاع على نموذج التطبيق.
إضافة الحساب الذي يتطلبه إطار العمل
يتطلب إطار عمل محوّل المزامنة أن يكون لكل محوّل مزامنة نوع حساب. لقد أعلنت
قيمة نوع الحساب في القسم
إضافة ملف البيانات الوصفية لأداة المصادقة. عليك الآن إعداد نوع الحساب هذا في نظام Android. لإعداد نوع الحساب، أضِف حسابًا نائبًا يستخدم نوع الحساب
من خلال طلب الرقم addAccountExplicitly()
.
وأفضل مكان لاستدعاء الطريقة هو طريقة onCreate()
لنشاط فتح تطبيقك. ويوضح مقتطف الرمز التالي كيفية إجراء ذلك:
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. */ } } ... }
إضافة ملف البيانات الوصفية لمحوّل المزامنة
لتوصيل مكوّن محوِّل المزامنة في إطار العمل، يجب تزويد إطار العمل
بالبيانات الوصفية التي تصف المكوِّن وتوفر علامات إضافية. وتحدِّد البيانات الوصفية نوع الحساب الذي أنشأته لمحوّل المزامنة، وتعلن عن مرجع موفّر المحتوى المرتبط بتطبيقك، وتتحكّم في جزء من واجهة مستخدم النظام المرتبط بمحوّلات المزامنة، وتعلن عن العلامات الأخرى ذات الصلة بالمزامنة. يُرجى تعريف هذه البيانات الوصفية في ملف XML خاص مخزّن في دليل /res/xml/
ضمن مشروع تطبيقك. يمكنك تسمية الملف بأي اسم،
علمًا أنّه عادةً ما يُسمى syncadapter.xml
.
يحتوي ملف XML هذا على عنصر XML واحد <sync-adapter>
يحتوي على السمات التالية:
android:contentAuthority
-
مرجع معرّف الموارد المنتظم (URI) لموفّر المحتوى إذا أنشأت موفّر محتوى الترنات الخاملة لتطبيقك في الدرس السابق إنشاء موفِّر محتوى صور غير مرغوب فيها، استخدِم القيمة التي حددتها للسمة
android:authorities
في العنصر<provider>
الذي أضفته إلى بيان التطبيق. يتم توضيح هذه السمة بمزيد من التفصيل في القسم تعريف الموفّر في البيان.
في حال نقل البيانات من موفّر محتوى إلى خادم يحتوي على محوّل المزامنة، يجب أن تكون هذه القيمة مطابقة لمرجع معرّف الموارد المنتظم للمحتوى الذي تستخدمه لهذه البيانات. هذه القيمة هي أيضًا إحدى القيم المرجعية التي تحدّدها في السمةandroid:authorities
في العنصر<provider>
، والتي تشير إلى مقدّم الخدمة في بيان التطبيق. android:accountType
-
نوع الحساب الذي يطلبه إطار عمل محوّل المزامنة. يجب أن تكون القيمة هي نفسها قيمة نوع الحساب التي قدّمتها عند إنشاء ملف البيانات الوصفية لأداة المصادقة، كما هو موضّح في القسم إضافة ملف البيانات الوصفية لأداة المصادقة. وهي أيضًا القيمة التي حدّدتها لـ
ACCOUNT_TYPE
الثابت في مقتطف الرمز في القسم إضافة الحساب مطلوب بواسطة إطار العمل. - سمات الإعدادات
-
-
android:userVisible
- لضبط إذن الوصول إلى نوع حساب محوِّل المزامنة. بشكل تلقائي، يظهر رمز الحساب وتصنيفه المرتبطان بنوع الحساب في قسم الحسابات في تطبيق إعدادات النظام، لذا يجب أن تجعل محوّل المزامنة غير مرئي ما لم يكن لديك نوع حساب أو نطاق يمكن ربطه بسهولة بتطبيقك. وإذا أخفيت نوع حسابك غير المرئي، سيظل بإمكانك السماح للمستخدمين بالتحكّم في محوّل المزامنة من خلال واجهة مستخدم في أحد أنشطة تطبيقك.
-
android:supportsUploading
-
يتيح لك تحميل البيانات إلى السحابة الإلكترونية. يجب ضبط القيمة على
false
إذا كان تطبيقك ينزّل البيانات فقط. -
android:allowParallelSyncs
- يسمح بتشغيل نُسخ متعددة من مكوّن محوِّل المزامنة في الوقت نفسه. استخدِم هذا الخيار إذا كان تطبيقك يتيح استخدام حسابات مستخدمين متعددة وكنت تريد السماح لعدة مستخدمين بنقل البيانات بالتوازي. ليس لهذه العلامة أي تأثير في حال عدم تنفيذ عدة عمليات نقل بيانات مطلقًا.
-
android:isAlwaysSyncable
-
تشير إلى إطار عمل محوّل المزامنة الذي يمكنه تشغيل محوّل المزامنة في أي
وقت تحدّده. إذا كنت تريد التحكم آليًا في وقت تشغيل
محوّل المزامنة، اضبط هذه العلامة على
false
، ثم اطلبrequestSync()
لتشغيل محوّل المزامنة. لمعرفة المزيد من المعلومات حول تشغيل محوِّل المزامنة، يُرجى الاطّلاع على الدرس تشغيل محوِّل المزامنة
-
يوضّح المثال التالي ملف XML لمحوّل مزامنة يستخدم حسابًا واحدًا نائبًا ويُجري عمليات التنزيل فقط.
<?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"/>
تعريف محوِّل المزامنة في البيان
بعد إضافة مكوِّن محوِّل المزامنة إلى تطبيقك، عليك طلب الأذونات
ذات الصلة باستخدام المكوِّن، وعليك الإفصاح عن Service
المرتبط
الذي أضفته.
وبما أنّ مكوّن محوّل المزامنة يُشغِّل رمزًا ينقل البيانات بين الشبكة والجهاز، ستحتاج إلى طلب إذن للوصول إلى الإنترنت. بالإضافة إلى ذلك، يحتاج تطبيقك إلى طلب إذن لقراءة إعدادات محوِّل المزامنة وكتابتها حتى تتمكن من التحكم في محوّل المزامنة آليًا من مكوّنات أخرى في تطبيقك. وعليك أيضًا طلب إذن خاص يسمح لتطبيقك باستخدام مكوّن المصادقة الذي أنشأته في الدرس إنشاء أداة مصادقة Stub Authenticator.
لطلب هذه الأذونات، أضِف ما يلي إلى بيان التطبيق كعناصر فرعية من
<manifest>
:
-
android.permission.INTERNET
- يسمح هذا الإذن لرمز محول المزامنة بالوصول إلى الإنترنت حتى يتمكّن من تنزيل البيانات أو تحميلها من الجهاز إلى خادم. ولن تحتاج إلى إضافة هذا الإذن مرة أخرى إذا كنت تطلبه في السابق.
-
android.permission.READ_SYNC_SETTINGS
-
يسمح هذا الإذن لتطبيقك بقراءة الإعدادات الحالية لمحوّل المزامنة. على سبيل المثال، يجب أن يكون لديك هذا
الإذن لطلب الاتصال بـ
getIsSyncable()
. -
android.permission.WRITE_SYNC_SETTINGS
-
يسمح هذا الإذن للتطبيق بالتحكّم في إعدادات محوّل المزامنة. عليك الحصول على هذا الإذن لضبط عمليات تشغيل محوّل المزامنة الدورية باستخدام
addPeriodicSync()
. هذا الإذن غير مطلوب لاستدعاء "requestSync()
". لمعرفة المزيد من المعلومات حول تشغيل محوِّل المزامنة، يُرجى الاطّلاع على تشغيل محوِّل المزامنة.
ويوضّح المقتطف التالي كيفية إضافة الأذونات:
<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>
أخيرًا، للإعلان عن Service
الالتزام الذي يستخدمه إطار العمل
للتفاعل مع محوّل المزامنة، يُرجى إضافة ملف XML التالي إلى بيان التطبيق كعنصر ثانوي
في <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>
يُعدّ العنصر <intent-filter>
فلترًا يتم تشغيله من خلال إجراء الغرض android.content.SyncAdapter
، ويرسله النظام لتشغيل محوّل المزامنة. عند تشغيل الفلتر، يبدأ النظام خدمة الربط التي أنشأتها، وهي الخدمة SyncService
في هذا المثال. تسمح السمة
android:exported="false"
لتطبيقك والنظام فقط بالوصول إلى
Service
. تطلب السمة
android:process=":sync"
من النظام تشغيل Service
في عملية مشتركة عامة تُسمى
sync
. إذا كان لديك عدة محوّلات مزامنة في تطبيقك، يمكن لهذه المحوّلات مشاركة هذه العملية،
ما يقلل النفقات العامة.
يوفّر العنصر <meta-data>
اسم ملف XML الذي أنشأته في السابق للبيانات الوصفية لمحوّل المزامنة.
تشير السمة
android:name
إلى أنّ البيانات الوصفية هذه مخصّصة لإطار عمل محوّل المزامنة. يحدّد العنصر android:resource
اسم ملف البيانات الوصفية.
لديك الآن جميع مكونات محوّل المزامنة. يوضّح الدرس التالي كيفية إعلام إطار عمل محوّل المزامنة بتشغيل محوّل المزامنة، إما استجابةً لحدث أو وفقًا لجدول زمني منتظم.