Projektuję aplikację, która ma cykliczne zadanie wysyłania informacji o obecności do serwera dedykowanego, o ile aplikacja jest na pierwszym planie.
W moich poszukiwaniach w Internecie widziałem kilka różnych podejść i chciałem wiedzieć, jaki jest najlepszy sposób zrobienia tego.
Jaki jest najlepszy sposób zaplanowania połączenia z serwerem?
Opcje, które zobaczyłem, to:
Timer .
Serwis .
BroadcastReciever z AlarmManager .
Jakie jest Twoje zdanie?
EDYCJA:
Powodem, dla którego potrzebuję tego jest aplikacja oparta na czacie, która wysyła wszystkie działania użytkownika na zdalny serwer.
tj. użytkownik pisze wiadomość, użytkownik czyta wiadomość, użytkownik jest online, użytkownik jest offline itp.
Oznacza to, że raz na interwał muszę wysyłać serwerowi to, co robię, ponieważ otwieram pokój rozmów z innymi ludźmi, oni muszą wiedzieć, co robię.
Podobnie jak w przypadku mechanizmu informacji zwrotnej o wiadomościach WhatsApp:
EDYCJA NR 2:
Powtarzające się zadania powinny być teraz planowane prawie zawsze za pośrednictwem JobScheduler
interfejsu API (lub FirebaseJobDispatcher
dla niższych interfejsów API), aby zapobiec problemom z rozładowywaniem baterii, co można przeczytać w sekcji dotyczącej najważniejszych elementów szkolenia na temat Androida
EDYCJA NR 3:
FirebaseJobDispatcher został wycofany i zastąpiony przez Workmanager , który zawiera również funkcje JobScheduler.
źródło
Odpowiedzi:
Nie jestem pewien, ale zgodnie ze swoją wiedzą podzielam swoje poglądy. Zawsze przyjmuję najlepszą odpowiedź, jeśli się mylę.
Menedżer alarmów
Menedżer alarmów utrzymuje blokadę wybudzenia CPU tak długo, jak długo
onReceive()
wykonywana jest metoda odbiornika alarmów . Gwarantuje to, że telefon nie będzie spał, dopóki nie zakończysz obsługi transmisji. PoonReceive()
powrocie Menedżer alarmów zwalnia blokadę wybudzenia. Oznacza to, że w niektórych przypadkach telefon będzie spać zaraz po zakończeniuonReceive()
metody. Jeśli zadzwonił Twój odbiornik alarmuContext.startService()
, możliwe jest, że telefon zostanie uśpiony przed uruchomieniem żądanej usługi. Aby temu zapobiec, swojeBroadcastReceiver
iService
będą musiały wdrożyć oddzielną politykę blokady obudzić, aby zapewnić, że telefon nadal działa aż usługa będzie dostępna.Uwaga: Menedżer alarmów jest przeznaczony dla przypadków, w których chcesz, aby kod aplikacji był uruchamiany o określonej godzinie, nawet jeśli aplikacja nie jest aktualnie uruchomiona. W przypadku normalnych operacji związanych z synchronizacją (takty, przekroczenia limitu czasu itp.) Korzystanie z programu Handler jest łatwiejsze i bardziej wydajne.
Regulator czasowy
Timer
ma pewne wady, które rozwiązujeScheduledThreadPoolExecutor
. Więc to nie jest najlepszy wybórScheduledThreadPoolExecutor .
Możesz użyć
java.util.Timer
lubScheduledThreadPoolExecutor
(preferowane), aby zaplanować akcję wykonywaną w regularnych odstępach czasu w wątku w tle.Oto próbka wykorzystująca to drugie:
Więc wolałem
ScheduledExecutorService
Ale pomyśl również o tym, że jeśli aktualizacje pojawią się, gdy aplikacja jest uruchomiona, możesz użyć
Timer
, jak sugerowano w innych odpowiedziach, lub nowszejScheduledThreadPoolExecutor
. Jeśli Twoja aplikacja będzie aktualizowana nawet wtedy, gdy nie jest uruchomiona, powinieneś użyć rozszerzeniaAlarmManager
.Zwróć uwagę, że jeśli planujesz aktualizację, gdy aplikacja jest wyłączona, raz na dziesięć minut jest dość częste, a zatem może być trochę zbyt energochłonne.
źródło
Regulator czasowy
Jak wspomniano w javadocs , lepiej jest używać ScheduledThreadPoolExecutor.
ScheduledThreadPoolExecutor
Użyj tej klasy, gdy Twój przypadek użycia wymaga wielu wątków roboczych, a interwał uśpienia jest mały. Jaki mały ? Cóż, powiedziałbym, że około 15 minut. W
AlarmManager
tym czasie rozpoczyna się planowanie odstępów czasu i wydaje się sugerować, że w przypadku mniejszych okresów snu można zastosować tę klasę. Nie mam danych, aby poprzeć ostatnie oświadczenie. To jest przeczucie.Usługa
Twoja usługa może zostać zamknięta w dowolnym momencie przez maszynę wirtualną. Nie używaj usług do zadań cyklicznych. Cykliczne zadanie może uruchomić usługę, co jest zupełnie inną sprawą.
BroadcastReciever z AlarmManager
W przypadku dłuższych przerw w spaniu (> 15 minut) jest to właściwy sposób.
AlarmManager
ma już stałe (AlarmManager.INTERVAL_DAY
) sugerujące, że może wyzwalać zadania kilka dni po ich pierwotnym zaplanowaniu. Może również obudzić procesor, aby uruchomić kod.Należy użyć jednego z tych rozwiązań w oparciu o czas i potrzeby wątku roboczego.
źródło
Zdaję sobie sprawę, że to stare pytanie i na które udzielono odpowiedzi, ale może to komuś pomóc. W Twoim
activity
W
onCreate
źródło
Cytowanie harmonogramu powtarzających się alarmów - Zapoznaj się z dokumentami dotyczącymi kompromisów :
Na tej podstawie najlepszym sposobem zaplanowania połączenia z serwerem jest użycie Google Cloud Messaging (GCM) w połączeniu z adapterem synchronizacji .
źródło
Utworzyłem na czas zadanie, w którym zadanie, które użytkownik chce powtarzać, dodaję w metodzie Custom TimeTask run (). powtarza się ponownie.
}
źródło