Różnice między Intent i PendingIntent

98

Przeczytałem kilka artykułów i oba wydają się robić to samo i zastanawiałem się, jaka jest różnica między uruchomieniem usługi w ten sposób:

Intent intent = new Intent(this, HelloService.class);
startService(intent);

lub tak:

Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent); 

Jak przeczytałem, te dwa robią to samo, jeśli w usłudze zwrócisz parametr START_STICKY;

user3629316
źródło
Nie ma różnicy. Co sprawia, że ​​myślisz, że będzie? W pierwszym przypadku zaczynasz to „teraz”, aw drugim po prostu planujesz to na późniejszy czas / dane.
Squonk,
Możliwy duplikat What is an Android PendingIntent?
James Moore,

Odpowiedzi:

154

Zamiar

Intencja Androida to obiekt przenoszący intencję, tj. Wiadomość z jednego komponentu do innego komponentu wewnątrz lub na zewnątrz aplikacji. Intencje mogą przekazywać komunikaty między dowolnym z trzech podstawowych składników aplikacji - działaniami, usługami i odbiornikami transmisji.

Sam zamiar, obiekt intencji, jest pasywną strukturą danych. Zawiera abstrakcyjny opis operacji do wykonania.

Na przykład: załóżmy, że masz działanie, które wymaga uruchomienia klienta poczty e-mail i wysłania wiadomości e-mail. Aby to zrobić, Twoje działanie wyśle ​​intencję z akcją ACTION_SENDwraz z odpowiednim wyborem do narzędzia do rozpoznawania intencji Androida:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this

Określony selektor zapewnia użytkownikowi odpowiedni interfejs do wyboru sposobu wysyłania danych e-mail.

JASNE ZAMIERZENIA

// Explicit Intent by specifying its class name
   Intent i = new Intent(this, TargetActivity.class);
   i.putExtra("Key1", "ABC");
   i.putExtra("Key2", "123");

// Starts TargetActivity
   startActivity(i);

IMPLICYJNE CELE

// Implicit Intent by specifying a URI
   Intent i = new Intent(Intent.ACTION_VIEW, 
   Uri.parse("http://www.example.com"));

// Starts Implicit Activity
   startActivity(i); 

Oczekujący zamiar

PendingIntent to token, który dajesz obcej aplikacji (np. NotificationManager, AlarmManager, Home Screen AppWidgetManager lub innym aplikacjom innych firm), który umożliwia zagranicznej aplikacji wykorzystanie uprawnień Twojej aplikacji do wykonania predefiniowanego fragmentu kodu.

Nadając PendingIntent innej aplikacji, dajesz jej prawo do wykonania operacji, którą określiłeś, tak jakby ta inna aplikacja była sobą (z tymi samymi uprawnieniami i tożsamością). W związku z tym powinieneś uważać na to, jak budujesz PendingIntent: prawie zawsze, na przykład podstawowa intencja, którą dostarczasz, powinna mieć jawnie ustawioną nazwę komponentu na jeden z twoich własnych komponentów, aby upewnić się, że zostanie ostatecznie wysłany tam i nigdzie indziej.

Przykład oczekującego zamiaru: http://android-pending-intent.blogspot.in/

Źródło: zamiary Androida i oczekujące zamiary Androida

Mam nadzieję że to pomoże.

Siddharth_Vyas
źródło
26

PendingIntentjest opakowaniem Intent. Zagraniczna aplikacja, która odbiera PendingIntent, nie wie, Intentktóra zawartość jest opakowana PendingIntent. Misją aplikacji zagranicznej jest odesłanie intencji do właściciela, gdy zostaną spełnione pewne warunki (na przykład: alarm z harmonogramem, powiadomienie kliknięciem ...). Warunki są podawane przez właściciela, ale przetwarzane przez zagraniczną aplikację (na przykład: alarm, powiadomienie).

Jeśli zagraniczna aplikacja wysłała intencję do Twojej aplikacji, oznacza to, że zagraniczna aplikacja wie o treści intencji. i aplikacja zagraniczna podejmie decyzję o wysłaniu zamiaru, wtedy Twoja aplikacja musi przetworzyć zamiar, aby spełnić pewne warunki => Twoja aplikacja uzyska zasoby wydajności systemu.

HungNM2
źródło
5

Kolejna prosta różnica:

  • Normalny zamiar umrze, gdy tylko aplikacja zostanie zabita.

  • Oczekujące intencje nigdy nie umierają. Będą żyli tak długo, jak będzie to potrzebne przez usługę alarmową, usługę lokalizacyjną lub jakąkolwiek inną usługę.

Zumry Mohamed
źródło
1

Regularne uruchamianie usług przez AlarmManager

Podobnie jak w przypadku działań, system Android może w każdej chwili zakończyć proces usługi w celu oszczędzania zasobów. Z tego powodu nie można po prostu użyć TimerTaskw usłudze, aby upewnić się, że jest wykonywana regularnie.

Dlatego do prawidłowego planowania Usługi należy użyć AlarmManagerklasy.

AKTUALIZACJA:

Więc nie ma między nimi żadnej różnicy. Ale w zależności od tego, czy chcesz zapewnić wykonanie usługi, czy nie, możesz zdecydować, z czego skorzystać, ponieważ na pierwszą nie ma gwarancji, a na późniejszą .

Więcej informacji na AndroidServices .

Mój Boże
źródło
2
To właściwie nie odpowiada na pytanie OP, które brzmi „jaka jest różnica” między bezpośrednim uruchomieniem usługi a uruchomieniem usługi z alarmem. Również OP prawdopodobnie widział artykuł, do którego odsyłasz, ponieważ kod w artykule jest prawie identyczny z tym, co opublikował OP.
Squonk,
Czy masz na myśli, że uruchomienie usługi z AlarmManager jest bezpieczniejsze i mniej prawdopodobne, że zostanie zabity niż w wyniku działania? Myślę, że to źle. Czy możesz wyjaśnić. @VedPrakash. Co więcej, myślę, że ważniejszy jest kontekst, który mija się podczas tworzenia zamiaru uruchomienia usługi. Bezpieczniejsze powinno być używanie kontekstu aplikacji (getApplicationContext ()) zamiast kontekstu działania (this).
Parth Kapoor
@ Eu.Dr. Polecam skorzystanie z menedżera alarmów, który będzie uruchamiany za każdym razem, gdy X ... wykonaj zadanie .. Dlaczego? ponieważ jeśli korzystasz z usług, w pewnym momencie może on zostać zamknięty i możesz w końcu pominąć niektóre aktualizacje w określonym czasie (nieznane). W przypadku wątpliwości dotyczących kontekstu, nigdy nie używaj go getApplicationContext()ani nie używaj go, gdy chcesz go ściśle, po prostu przeczytaj - kiedy-to-wywołać-kontekst-działania-lub-kontekst-aplikacji ( stackoverflow.com/questions/7298731/ ... ).
Mój Boże,
1

Funkcjonalnie nie ma różnicy.

Znaczenie PendingIntent polega na tym, że możesz obsłużyć go do innej aplikacji, która później będzie mogła go używać tak, jakby ta inna aplikacja była sobą. Oto odpowiednie wyjaśnienie z dokumentacji :

Nadając PendingIntent innej aplikacji, dajesz jej prawo do wykonania operacji, którą określiłeś, tak jakby ta inna aplikacja była sobą (z tymi samymi uprawnieniami i tożsamością). W związku z tym powinieneś uważać na to, jak budujesz PendingIntent: prawie zawsze, na przykład podstawowa intencja, którą dostarczasz, powinna mieć jawnie ustawioną nazwę komponentu na jeden z twoich własnych komponentów, aby upewnić się, że zostanie ostatecznie wysłany tam i nigdzie indziej.

Sam PendingIntent jest po prostu odniesieniem do tokenu utrzymywanego przez system, opisującego oryginalne dane użyte do ich pobrania.

Więc PendingIntent jest po prostu odwołaniem do danych, które reprezentują pierwotną intencję (która została użyta do utworzenia PendingIntent).

kupsef
źródło
4
Mówienie, że funkcjonalnie nie ma różnicy, jest błędne. Jeśli funkcje obu są takie same, to po co dwa na pierwszym miejscu? Najważniejsza różnica polega na tym, że PendingIntent jest wykonywany przez zdalny komponent (taki jak NotificationManager) z tymi samymi uprawnieniami, co komponent, który go przekazuje (ten, który tworzy powiadomienie).
Aniket Thakur