Tworzenie adaptera synchronizacji

Uwaga: zalecamy korzystanie z WorkManagera jako zalecane rozwiązanie w większości przypadków użycia związanych z przetwarzaniem w tle. Zapoznaj się z przewodnika po przetwarzaniu w tle, by dowiedzieć się, które rozwiązanie jest dla Ciebie najlepsze.

Komponent adaptera synchronizacji w aplikacji umieszcza kod dla zadań, które są przenoszone między urządzeniem a serwerem. Na podstawie harmonogramu i reguł podanych przez Ciebie w aplikacji, platforma adaptera synchronizacji uruchamia kod komponentu adaptera synchronizacji. Aby dodać adapter do aplikacji, musisz dodać te elementy:

Synchronizuj klasę adaptera.
Klasa, która opakowuje kod przenoszenia danych w interfejsie zgodnym z adapterem synchronizacji. platformy.
Łączenie z Service.
Komponent umożliwiający platformie adaptera synchronizacji uruchomienie kodu w adapterze synchronizacji zajęcia.
Synchronizacja pliku XML metadanych adaptera.
Plik zawierający informacje o adapterze synchronizacji. Platforma odczytuje ten plik do dowiedz się, jak wczytać i zaplanować przenoszenie danych.
Deklaracje w manifeście aplikacji.
Kod XML z deklaracją powiązanej usługi i wskazującą synchronizację metadanych związanych z adapterem.

Z tej lekcji dowiesz się, jak zdefiniować te elementy.

Tworzenie klasy adaptera synchronizacji

W tej części lekcji dowiesz się, jak utworzyć klasę adaptera synchronizacji, która zawiera kod transferu danych. Utworzenie klasy obejmuje rozszerzenie klasy bazowej adaptera synchronizacji, zdefiniowanie konstruktory dla klasy i implementowanie metody, w której definiuje się przesyłanie danych zadania.

Rozszerz podstawową klasę adaptera synchronizacji

Aby utworzyć komponent adaptera synchronizacji, zacznij od rozszerzenia AbstractThreadedSyncAdapter i tworzeniu jego konstruktorów. Użyj konstruktory do uruchamiania zadań konfiguracyjnych za każdym razem, gdy na podstawie komponentu adaptera synchronizacji jest tworzony tak samo jak za pomocą usługi Activity.onCreate() działania. Jeśli na przykład aplikacja korzysta z usług dostawcy treści do przechowywania danych, użyj konstruktorów aby pobrać instancję ContentResolver. Ponieważ druga forma atrybutu został dodany do platformy Androida 3.0 w celu obsługi parallelSyncs , musisz utworzyć dwie formy konstruktora, aby zachować zgodność.

Uwaga: platforma adaptera synchronizacji jest przeznaczona do współpracy z adapterem synchronizacji które są instancjami pojedynczymi. Tworzenie instancji komponentu adaptera synchronizacji jest omówione bardziej szczegółowo w sekcji Powiąż adapter synchronizacji z platformą.

Poniższy przykład pokazuje, jak zaimplementować AbstractThreadedSyncAdapteri jego konstruktory:

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();
        ...
    }

Dodawanie kodu przenoszenia danych

Komponent adaptera synchronizacji nie wykonuje automatycznego przenoszenia danych. Zamiast tego otacza kod transferu danych, aby platforma adaptera synchronizacji mogła uruchamiać i przesyłanie danych w tle bez udziału aplikacji. Gdy platforma jest gotowa synchronizacji danych aplikacji wywołuje implementację metody onPerformSync()

Aby ułatwić przenoszenie danych z głównego kodu aplikacji do komponentu adaptera synchronizacji, wywołania platformy adaptera synchronizacji onPerformSync() z następujące argumenty:

Konto
Obiekt Account powiązany ze zdarzeniem, które wywołało lub adapter synchronizacji. Jeśli serwer nie korzysta z kont, nie musisz używać metody w tym obiekcie.
Dodatkowe treści
Pole Bundle zawierające flagi wysłane przez zdarzenie, które uruchomiło synchronizację przejściówkę.
Wiarygodność
Uprawnienia dostawcy treści w systemie. Aplikacja musi mieć dostęp do tych elementów: u tego dostawcy. Zwykle urząd odpowiada dostawcy treści w Twojej aplikacji.
.
Klient dostawcy treści
ContentProviderClient dla dostawcy treści wskazywanego przez parametr argumentu władzy. ContentProviderClient to lekka wersja publiczna z dostawcą treści. Ma te same podstawowe funkcje co ContentResolver Jeśli korzystasz z usług dostawcy treści do przechowywania danych aplikacji, możesz połączyć się z dostawcą za pomocą tego obiektu. W przeciwnym razie możesz zignorować .
Wynik synchronizacji
Obiekt SyncResult używany do wysyłania informacji do synchronizacji i różnic między nimi.

Ten fragment kodu przedstawia ogólną strukturę 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.
     */
}

Chociaż rzeczywiste wdrożenie onPerformSync() dotyczy wymagań aplikacji w zakresie synchronizacji danych i protokołów połączeń z serwerem, istnieje kilka ogólne zadania, które powinna wykonać Twoja implementacja:

Łączenie z serwerem
Można przyjąć, że w momencie rozpoczęcia przenoszenia danych sieć jest dostępna, jednak platforma adaptera synchronizacji nie łączy się automatycznie z serwerem.
Pobieranie i przesyłanie danych
Adapter synchronizacji nie automatyzuje żadnych zadań związanych z przesyłaniem danych. Jeśli chcesz pobrać z serwera i zapisują je u dostawcy treści, musisz dostarczyć kod, który pobiera dane, pobiera je i wstawia u dostawcy. Podobnie, jeśli chcesz aby wysłać dane na serwer, trzeba je odczytać z pliku, bazy danych lub dostawcy i wysłać z niezbędną prośbą o przesłanie. Musisz też radzić sobie z błędami sieciowymi, które występują podczas korzystania trwa przesyłanie danych.
radzić sobie z konfliktami danych i określać ich aktualność;
Adapter synchronizacji nie obsługuje automatycznie konfliktów między danymi na serwerze a danymi na urządzeniu. Ponadto nie wykrywa automatycznie, czy dane na serwerze są nowsze niż z danymi na urządzeniu lub odwrotnie. Zamiast tego musisz utworzyć własne algorytmy dla radzenia sobie z taką sytuacją.
Wyczyść dane.
Zawsze zamykaj połączenia z serwerem i wyczyść pliki tymczasowe oraz pamięci podręczne na końcu i przeniesieniu danych.

Uwaga: działa platforma adaptera synchronizacji onPerformSync() w: , dzięki czemu nie musisz konfigurować własnego przetwarzania w tle.

Oprócz wykonywania zadań związanych z synchronizacją warto też połączyć zadania związane z siecią i dodawanie ich do onPerformSync() Skupienie na tej metodzie wszystkich zadań sieciowych pozwala oszczędzać energię baterii potrzebne do uruchamiania i zatrzymywania interfejsów sieci. Więcej informacji o zwiększaniu dostępu do sieci znajdziesz w lekcji Przenoszenie danych bez wyczerpywania baterii, w której omawiamy zagadnienia związane z dostępem do różnych sieci które można uwzględnić w kodzie przenoszenia danych.

Powiąż adapter synchronizacji ze platformą

Kod transferu danych jest teraz zawarty w elemencie adaptera synchronizacji, ale masz też aby zapewnić platformie dostęp do kodu. Aby to zrobić, musisz utworzyć powiązanie Service, który przekazuje specjalny obiekt powiązania Androida z adaptera synchronizacji. do struktury. Za pomocą tego obiektu powiązania platforma może wywoływać metodę onPerformSync() i i przekazywać do niego dane.

Utwórz wystąpienie komponentu adaptera synchronizacji jako pojedynczy element Metoda onCreate() usługi. Przez utworzenie instancji komponentu w onCreate(), opóźnisz i tworzy go do momentu uruchomienia usługi, co ma miejsce, gdy platforma po raz pierwszy próbuje uruchomić przesyłanie danych. Wystąpienie komponentu należy utworzyć w sposób zapewniający ochronę wątków na wypadek, gdyby synchronizacja platforma adaptacyjna umieszcza w kolejce wiele uruchomień adaptera synchronizacji w odpowiedzi na aktywatory lub harmonogram.

Na przykład ten fragment kodu pokazuje, jak utworzyć klasę, która umieszcza bound (Service), tworzy instancję komponentu adaptera synchronizacji i pobiera Obiekt powiązania Androida:

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();
    }
}

Uwaga: aby zobaczyć bardziej szczegółowy przykład usługi powiązanej z adapterem synchronizacji, znajdziesz w przykładowej aplikacji.

Dodaj konto wymagane przez platformę

Platforma adaptera synchronizacji wymaga, aby każdy adapter synchronizacji miał typ konta. Zadeklarowano wartość typu konta w sekcji, Dodaj plik metadanych z aplikacji Authenticator. Teraz musisz skonfigurować ten rodzaj konta w System Android. Aby skonfigurować rodzaj konta, dodaj konto zastępcze, które korzysta z jego typu dzwoniąc pod numer addAccountExplicitly().

Najlepszym miejscem do wywołania tej metody jest Metoda onCreate() Twojej aplikacji podczas otwierania. Fragment kodu, który pokazuje, jak to zrobić:

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.
             */
        }
    }
    ...
}

Dodaj plik metadanych adaptera synchronizacji

Aby podłączyć komponent adaptera synchronizacji do platformy, musisz udostępnić platformę z metadanymi, które opisują komponent i zawierają dodatkowe flagi. Metadane określają, typ konta utworzony na potrzeby adaptera synchronizacji deklaruje urząd dostawcy treści powiązanego z aplikacją – kontroluje część interfejsu systemowego związaną z adapterami synchronizacji, i deklaruje inne flagi związane z synchronizacją. Zadeklaruj te metadane w specjalnym pliku XML przechowywanym w katalogu /res/xml/ w projekcie aplikacji. Plikowi możesz nadać dowolną nazwę, ale zwykle się nazywa syncadapter.xml.

Ten plik XML zawiera jeden element XML <sync-adapter>, który zawiera parametr następujące atrybuty:

android:contentAuthority
Urząd URI dostawcy treści Jeśli został utworzony dostawca treści dla aplikacji w poprzedniej lekcji Tworzenie dostawcy treści Stub, użyj wartości określonej dla atrybutu atrybut android:authorities w elemencie <provider> dodanym do pliku manifestu aplikacji. Ten atrybut jest omówiono to szczegółowo w sekcji Zadeklaruj dostawcę w pliku manifestu.
Jeśli przenosisz dane od dostawcy treści na serwer za pomocą adaptera synchronizacji, powinna być taka sama jak identyfikator URI treści, którego używasz w przypadku tych danych. Ta wartość jest również jednym z organów wskazanych w android:authorities w elemencie <provider> deklarującego dostawcę w manifeście aplikacji.
android:accountType
Rodzaj konta wymagany przez platformę adaptera synchronizacji. Wartość musi być taka sama jako wartość typu konta podaną przy tworzeniu pliku metadanych uwierzytelniania, opisane w sekcji Dodawanie pliku metadanych Authenticator. Jest to również wartość podana w atrybucie stała ACCOUNT_TYPE we fragmencie kodu w sekcji Dodaj konto wymagane przez platformę.
Atrybuty ustawień
android:userVisible
Ustawia widoczność typu konta adaptera synchronizacji. Domyślnie atrybut ikonę i etykietę powiązaną z typem konta są widoczne w Konta w systemowej aplikacji Ustawienia, więc musisz przeprowadzić synchronizację. Adapter jest niewidoczny, chyba że masz konto lub domenę, które można łatwo powiązać z Twoją aplikacją. Nawet jeśli ustawisz swój rodzaj konta jako niewidoczny, nadal możesz zezwolić użytkownikom na kontrolować adapter synchronizacji za pomocą interfejsu w jednej z aktywności w aplikacji.
android:supportsUploading
Umożliwia przesyłanie danych do chmury. Ustaw jako false, jeśli Twoja aplikacja pobiera dane.
android:allowParallelSyncs
Umożliwia jednoczesne uruchamianie wielu wystąpień komponentu adaptera synchronizacji. Użyj go, jeśli aplikacja obsługuje wiele kont użytkowników i chcesz zezwolić na korzystanie z wielu kont użytkowników, aby przenosić dane równolegle. Ta flaga nie działa, jeśli nigdy nie jest uruchamiana wielu transferów danych.
android:isAlwaysSyncable
Wskazuje platformę adaptera synchronizacji, że może ona uruchomić adapter synchronizacji w dowolnym momencie w wybranym przez Ciebie czasie. Jeśli chcesz automatycznie kontrolować moment synchronizacji może działać adapter, ustaw tę flagę na false, a potem wywołaj requestSync(), aby uruchomić lub adapter synchronizacji. Więcej informacji o korzystaniu z adaptera synchronizacji można znaleźć w wykładzie Uruchamianie adaptera synchronizacji

Poniższy przykład pokazuje kod XML adaptera synchronizacji, który korzysta z jednego konta zastępczego tylko pobieranie.

<?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"/>

Zadeklaruj adapter synchronizacji w pliku manifestu

Po dodaniu do aplikacji komponentu adaptera synchronizacji musisz poprosić o uprawnienia związane z komponentem. Musisz zadeklarować Service dodany przez Ciebie.

Komponent adaptera synchronizacji uruchamia kod, który przesyła dane między siecią a urządzenia, musisz poprosić o pozwolenie na dostęp do internetu. Aplikacja musi też: aby poprosić o uprawnienia do odczytu i zapisu ustawień adaptera synchronizacji, aby móc kontrolować synchronizację z innych komponentów aplikacji. Musisz również poprosić o specjalne uprawnienie, które umożliwia aplikacji używanie utworzonego komponentu uwierzytelniającego w lekcji Tworzenie aplikacji Stub Authenticator.

Aby poprosić o te uprawnienia, dodaj do pliku manifestu aplikacji te elementy jako elementy podrzędne argumentu <manifest>:

android.permission.INTERNET
Zezwala kodowi adaptera synchronizacji na dostęp do internetu, aby mógł pobierać i przesyłać dane z urządzenia na serwer. Nie musisz ponownie dodawać tych uprawnień, jeśli: o przesłanie prośby o niego wcześniej.
android.permission.READ_SYNC_SETTINGS
Zezwala aplikacji na odczyt bieżących ustawień adaptera synchronizacji. Na przykład: aby wywołać getIsSyncable().
android.permission.WRITE_SYNC_SETTINGS
Zezwala aplikacji na kontrolowanie ustawień adaptera synchronizacji. Te uprawnienia są potrzebne, aby: ustaw używanie adaptera okresowego synchronizacji za pomocą interfejsu addPeriodicSync(). Te uprawnienia nie są wymagane do wywołania requestSync() Aby dowiedzieć się więcej o: uruchamianie adaptera synchronizacji zawiera artykuł Uruchamianie adaptera synchronizacji.

Ten fragment kodu pokazuje, jak dodać uprawnienia:

<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>

Na koniec należy zadeklarować granicę Service, której platforma używa do wejść w interakcję z adapterem synchronizacji, dodaj poniższy kod XML do pliku manifestu aplikacji jako element podrzędny z <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> konfiguruje filtr wywoływany przez działanie intencji android.content.SyncAdapter, wysyłane przez system w celu uruchomienia adaptera synchronizacji. Kiedy filtr system uruchomi powiązaną usługę, którą w tym przykładzie jest SyncService Atrybut android:exported="false" zapewnia dostęp tylko aplikacji i systemowi Service Atrybut android:process=":sync" informuje system, aby uruchomić Service w globalnym procesie współdzielonym o nazwie sync Jeśli masz w aplikacji wiele adapterów synchronizacji, mogą one współdzielić ten proces. co pozwala zmniejszyć koszty.

<meta-data> zawiera nazwę utworzonego wcześniej pliku XML metadanych adaptera synchronizacji. android:name wskazuje, że metadane dotyczą platformy adaptera synchronizacji. android:resource określa nazwę pliku metadanych.

Masz teraz wszystkie komponenty adaptera synchronizacji. Na następnej lekcji dowiesz się, jak nakazuje platformie adaptera synchronizacji uruchamianie adaptera synchronizacji w odpowiedzi na zdarzenie lub w sposób zrównoważony.