Різниця між наміром та наміром, що очікує на розгляд


97

Я читав деякі статті, і, здається, обидва роблять одне і те ж, і мені було цікаво, в чому різниця між таким запуском служби:

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

або так:

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

Коли я читав, ці двоє роблять те саме, якщо у службі ви повертаєте параметр START_STICKY;


Різниці немає. Що змушує вас думати, що це могло б бути? У першому випадку ви починаєте це "зараз", а у другому ви просто плануєте його на наступний час / дані.
Squonk

Відповіді:


150

Намір

Намір Android - це об’єкт, що несе за собою намір, тобто повідомлення від одного компонента до іншого компонента, що знаходиться всередині програми або поза нею. Наміри можуть обмінюватися повідомленнями з будь-яким із трьох основних компонентів програми - Діяльність, Послуги та Приймачі трансляції.

Сам намір, об'єкт Intent, є пасивною структурою даних. Він містить абстрактний опис операції, яку потрібно виконати.

Наприклад: скажімо, у вас є Activity, яка повинна запустити поштовий клієнт і надіслати електронне повідомлення. Для цього Ваша Діяльність надсилає Намір з дією ACTION_SEND, разом із відповідним вибором, на Android Intent Resolver:

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

Вказаний засіб вибору надає належний інтерфейс для вибору користувачем способу надсилання даних електронної пошти.

ВИРАЗНІ НАМІРИ

// 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);

ІМПЛІЦІТНІ НАМЕРИ

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

// Starts Implicit Activity
   startActivity(i); 

Очікує намір

PendingIntent - це маркер, який ви надаєте іноземній програмі (наприклад, NotificationManager, AlarmManager, Home Screen AppWidgetManager або інші сторонні програми), що дозволяє іноземній програмі використовувати дозволи вашої програми для виконання заздалегідь визначеного фрагмента коду.

Надаючи PendingIntent іншій програмі, ви надаєте їй право виконувати вказану вами операцію, ніби інша програма була вами (з тими самими дозволами та ідентифікацією). Таким чином, ви повинні бути обережними щодо того, як ви будуєте PendingIntent: майже завжди, наприклад, базовий Intent, який ви постачаєте, повинен мати ім'я компонента, явно встановлене на один із ваших власних компонентів, щоб переконатися, що воно в кінцевому підсумку надсилається туди і нікуди більше.

Приклад очікуваного наміру: http://android-pending-intent.blogspot.in/

Джерело: Android Intents та Android Pending Intents

Сподіваюся, це допомагає.


26

PendingIntentє обгорткою від Intent. Іноземна програма, яка отримує PendingIntent, не знає, вміст Intentякої обгорнуто PendingIntent. Місія іноземного додатка - повернути намір власнику, коли виконуються деякі умови (Наприклад: сигнал тривоги з розкладом або повідомлення натисканням ...). Умови надаються власником, але обробляються іноземним додатком (наприклад: сигналізація, сповіщення).

Якщо іноземна програма надіслала намір на ваш додаток, майте на увазі, що іноземна програма знає про зміст наміру. і іноземний додаток приймає рішення надіслати намір, тоді ваш додаток повинен обробити намір, щоб відповідати деяким умовам => ваш додаток отримає ресурс продуктивності системи.


5

Ще одна проста відмінність:

  • Звичайний намір помре, як тільки додаток буде вбито.

  • Очікувані наміри ніколи не вмирають. Вони будуть жити до тих пір, поки це буде потрібно службі сигналізації, службі визначення місцезнаходження або будь-яким іншим службам.


1

Регулярно запускати служби через AlarmManager

Як і у випадку з діяльністю, система Android може в будь-який час припинити процес надання послуги, щоб заощадити ресурси. З цієї причини ви не можете просто використовувати aTimerTask службу, щоб забезпечити її регулярне виконання.

Отже, для коректного планування Служби використовуйте AlarmManagerклас.

ОНОВЛЕННЯ:

Тож між ними немає фактичної різниці. Але залежно від того, чи хочете ви забезпечити виконання послуги чи ні, ви можете вирішити, що використовувати, оскільки для першого гарантія відсутня, а для наступного вона є.

Більше інформації на AndroidServices .


2
Це насправді не відповідає на запитання OP, яке полягає у тому, "в чому різниця" між безпосереднім запуском послуги та запуском служби з сигналізацією. Також ОП, мабуть, бачила статтю, на яку ви посилаєтесь, оскільки код у цій статті майже ідентичний тому, що опублікував ОР.
Squonk

Ви маєте на увазі, що запуск служби з AlarmManager безпечніший і з меншою ймовірністю буде вбитий, ніж через діяльність? Я вважаю, що це неправильно. Поясніть, будь ласка. @VedPrakash. Більше того, я думаю, що контекст, який ви передаєте, створюючи намір запустити послугу, є більш важливим. Використання контексту програми (getApplicationContext ()), а не контексту діяльності (this), має бути безпечнішим.
Парт Капур,

@ Eu.Dr. Я рекомендую вам скористатися диспетчером будильників, який запускатиметься щоразу, коли X ... виконуватиме завдання .. Чому? тому що, якщо ви користуєтесь послугами, вона може бути закрита в якийсь момент, і в кінцевому підсумку ви можете пропустити деякі оновлення в певний час (невідомо). Для сумнівів у контексті ніколи не використовуйте getApplicationContext()і не використовуйте його, коли ви цього хочете, строго, просто прочитайте - коли викликати-активність-контекст-або-застосунок-контекст ( stackoverflow.com/questions/7298731/… ).
Боже мій

1

Функціонально різниці немає.

Значення PendingIntent полягає в тому, що ви можете обробляти його в іншому додатку, який згодом може використовувати його, як якщо б інший додаток був вами самим. Ось відповідне пояснення з документації :

Надаючи PendingIntent іншій програмі, ви надаєте їй право виконувати вказану вами операцію, ніби інша програма була вами (з тими самими дозволами та ідентифікацією). Таким чином, ви повинні бути обережними щодо того, як ви будуєте PendingIntent: майже завжди, наприклад, базовий Intent, який ви постачаєте, повинен мати ім'я компонента, явно встановлене на один із ваших власних компонентів, щоб переконатися, що воно в кінцевому підсумку надсилається туди і нікуди більше.

Сам PendingIntent - це просто посилання на маркер, що підтримується системою, що описує вихідні дані, що використовуються для його отримання.

Отже, PendingIntent - це лише посилання на дані, що представляють вихідний намір (який використовувався для створення PendingIntent).


4
Твердження, що функціонально ніякої різниці немає, є неправильним. Якщо функції обох однакові, то навіщо дві на 1-му місці? Найважливіша відмінність у тому, що PendingIntent виконується віддаленим компонентом (як NotificationManager) з тими самими дозволами, що й той компонент, який передає його (той, який створює сповіщення).
Aniket Thakur
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.