Различия между Intent и PendingIntent

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;

user3629316
источник
Нет никакой разницы. Что заставляет вас думать, что это будет? В первом случае вы запускаете его «сейчас», а во втором вы просто планируете его на более позднее время / данные.
Squonk
Возможный дубликат сообщения Что такое ожидающее намерение Android?
Джеймс Мур

Ответы:

151

Намерение

Android Intent - это объект, несущий намерение, то есть сообщение от одного компонента другому компоненту внутри или вне приложения. Намерения могут передавать сообщения между любым из трех основных компонентов приложения - Activity, Services и BroadcastReceivers.

Само намерение, объект Intent, представляет собой пассивную структуру данных. Он содержит абстрактное описание операции, которую необходимо выполнить.

Например: скажем, у вас есть Activity, которому нужно запустить почтовый клиент и отправить электронное письмо. Для этого ваша Activity отправит Intent с действием 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: почти всегда, например, базовое намерение, которое вы предоставляете, должно иметь имя компонента, явно установленное для одного из ваших собственных компонентов, чтобы гарантировать, что он в конечном итоге будет отправлен туда и никуда больше.

Пример ожидающего намерения: http://android-pending-intent.blogspot.in/

Источник: Android Intents и Android В ожидании Intents

Надеюсь это поможет.

Siddharth_Vyas
источник
26

PendingIntentэто обертка Intent. Внешнее приложение, которое получает объект PendingIntent, не знает, что его содержимое Intentобернуто PendingIntent. Задача стороннего приложения - отправить обратно намерение владельцу при выполнении некоторых условий (например: сигнал тревоги с расписанием или уведомление с щелчком ...). Условия задаются владельцем, но обрабатываются сторонним приложением (например: тревога, уведомление).

Если иностранное приложение отправило намерение вашему приложению, это означает, что иностранное приложение знает о содержании намерения. и стороннее приложение принимает решение об отправке намерения, тогда ваше приложение должно обрабатывать намерение для удовлетворения некоторых условий => ваше приложение получает ресурс производительности системы.

HungNM2
источник
5

Еще одно простое отличие:

  • Обычное намерение умрет, как только приложение будет убито.

  • Незавершенные намерения никогда не умирают. Они будут живы до тех пор, пока это необходимо для службы сигнализации, службы определения местоположения или любых других служб.

Зумри Мохамед
источник
1

Регулярный запуск сервисов через AlarmManager

Как и в случае с действиями, система Android может прекратить процесс обслуживания в любое время для экономии ресурсов. По этой причине вы не можете просто использовать TimerTaskв службе, чтобы гарантировать, что она выполняется на регулярной основе.

Итак, для правильного планирования Сервиса используйте AlarmManagerкласс.

ОБНОВИТЬ:

Так что на самом деле между ними нет никакой разницы. Но в зависимости от того, хотите ли вы обеспечить выполнение услуги или нет, вы можете решить, что использовать, поскольку для первого нет гарантии, а для более позднего - да.

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

О Господи
источник
2
На самом деле это не отвечает на вопрос OP, который заключается в том, «в чем разница» между прямым запуском службы и запуском службы с сигналом тревоги. Кроме того, OP, вероятно, видел статью, на которую вы ссылаетесь, поскольку код в статье почти идентичен тому, что опубликовал OP.
Squonk
Вы имеете в виду, что запуск службы из AlarmManager безопаснее и с меньшей вероятностью будет убит, чем из-за действия? Я считаю это неправильным. Не могли бы вы объяснить. @VedPrakash. Более того, я думаю, что контекст, который вы передаете при создании намерения запустить службу, более важен. Использование контекста приложения (getApplicationContext ()), а не контекста действия (this), должно быть более безопасным.
Parth Kapoor
@ Eu.Dr. Я рекомендую вам использовать диспетчер тревог, который будет срабатывать каждый раз, когда X ... выполняет задачу .. Почему? потому что, если вы используете службы, они могут быть закрыты в какой-то момент, и вы можете пропустить некоторые обновления в определенное время (неизвестно). В случае сомнений по поводу контекста никогда не используйте getApplicationContext()и не используйте его, когда вы этого хотите, просто прочтите - when-to-call-activity-context-or-application-context ( stackoverflow.com/questions/7298731/… ).
Боже мой
1

Функционально разницы нет.

Значение PendingIntent состоит в том, что вы можете передать его другому приложению, которое позже может использовать его, как если бы это другое приложение было вами. Вот соответствующее объяснение из документации :

Предоставляя PendingIntent другому приложению, вы предоставляете ему право выполнять указанную вами операцию, как если бы это другое приложение было вами (с такими же разрешениями и идентификатором). Таким образом, вы должны быть осторожны с тем, как вы создаете PendingIntent: почти всегда, например, базовое намерение, которое вы предоставляете, должно иметь имя компонента, явно установленное для одного из ваших собственных компонентов, чтобы гарантировать, что он в конечном итоге будет отправлен туда и никуда больше.

Сам PendingIntent - это просто ссылка на токен, поддерживаемый системой, описывающий исходные данные, используемые для его получения.

Итак, PendingIntent - это просто ссылка на данные, представляющие исходное намерение (которое использовалось для создания PendingIntent).

Купсеф
источник
4
Сказать, что функциональной разницы нет, неверно. Если функции обоих одинаковы, то почему два на первом месте? Самое важное отличие в том, что PendingIntent выполняется удаленным компонентом (например, NotificationManager) с теми же разрешениями, что и у компонента, который передает его (тот, который создает уведомление).
Аникет Такур