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,则这两个函数的作用相同。


没有区别 是什么让您认为会有呢?在第一种情况下,您是“现在”启动它,在第二种情况下,您只是在稍后的时间/数据上计划它。
2014年

Answers:


150

意图

Android Intent是一个承载Intent的对象,即从一个组件到应用程序内部或外部的另一个组件的消息。意图可以在应用程序的三个核心组件(活动,服务和广播接收器)之间传递消息。

意图本身(一个意图对象)是一个被动数据结构。它包含要执行的操作的抽象描述。

例如:假设您有一个活动,需要启动电子邮件客户端并发送电子邮件。为此,您的Activity会将带有action的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,主屏幕AppWidgetManager或其他第三方应用程序)的令牌,它允许外部应用程序使用您的应用程序的权限来执行预定义的代码。

通过将PendingIntent赋予另一个应用程序,即授予它执行指定的操作的权限,就好像另一个应用程序是您自己一样(具有相同的权限和身份)。因此,您应该注意如何构建PendingIntent:例如,几乎总是,您提供的基本Intent应该将组件名称显式设置为您自己的组件之一,以确保最终将其发送到那里。

待定意图示例:http : //android-pending-intent.blogspot.in/

来源:Android IntentAndroid Pending Intent

希望这可以帮助。


26

PendingIntent是的包装Intent。收到的外部应用程序PendingIntent不知道其内容IntentPendingIntent。外部应用程序的任务是在满足某些条件时将意图发送回所有者(例如:带计划的警报或带单击的通知...)。条件由所有者给出,但由外国应用程序处理(例如:警报,通知)。

如果外部应用程序向您的应用程序发送了意图,则意味着该外国应用程序知道该意图的内容。并且外国应用程序决定发送意图,则您的应用程序必须处理意图以满足某些条件=>您的应用程序获得系统的性能资源。


5

另一个简单的区别:

  • 应用程序被杀死后,正常意图就会消失。

  • 待定的意图永远不会消失。只要警报服务,定位服务或任何其他服务需要它们,它们就可以存活。


1

通过AlarmManager定期启动服务

与活动一样,Android系统可以随时终止服务流程以节省资源。因此,您不能简单地TimerTask在服务中使用a 来确保定期执行该服务。

因此,为正确安排服务,请使用AlarmManager类。

更新:

因此,两者之间没有实际差异。但是取决于您是否要确保服务的执行,可以决定使用什么,对于前者没有保证,而对于后者则可以保证。

有关更多信息,请参见AndroidServices


2
这实际上并不能回答OP的问题,即直接启动服务与通过警报启动服务之间的“区别是什么”。另外,OP可能已经看到您链接到的文章,因为该文章中的代码与OP所发布的内容几乎相同。
Squonk 2014年

您是说从AlarmManager启动服务比从活动启动更安全,并且被杀死的可能性更低?我认为这是错误的。你能解释一下吗?@VedPrakash。而且,我认为您在创建启动服务意图时传递的上下文更加重要。使用应用程序的上下文(getApplicationContext())而不是活动的上下文(this)应该更安全。
Parth Kapoor 2014年

@ Eu.Dr。我建议您使用每次X ...执行任务时都会触发的警报管理器。为什么?因为如果使用服务,它可能会在某个时候关闭,并且最终可能会在某个时间跳过某些更新(未知)。出于上下文方面的疑问,切勿getApplicationContext()在严格需要的情况下使用或使用它,只需阅读-呼叫活动上下文或应用程序上下文时(stackoverflow.com/questions/7298731/…)。
我的上帝

1

在功能上没有区别。

PendingIntent的含义是,您可以将其处理到其他应用程序,以后再使用它,就好像另一个应用程序是您自己一样。这是文档中的相关说明:

通过将PendingIntent赋予另一个应用程序,即授予它执行指定的操作的权限,就好像另一个应用程序是您自己一样(具有相同的权限和身份)。因此,您应该注意如何构建PendingIntent:例如,几乎总是,您提供的基本Intent应该将组件名称显式设置为您自己的组件之一,以确保最终将其发送到那里。

PendingIntent本身只是对系统维护的令牌的引用,该令牌描述了用于检索令牌的原始数据。

因此,PendingIntent只是对表示原始Intent(用于创建PendingIntent的Intent)的数据的引用。


4
说在功能上没有区别是不正确的。如果两者的功能相同,那为什么要在第一位有两个?最重要的区别在于PendingIntent是由远程组件(如NotificationManager)执行的,其权限与移交它的组件(创建通知的组件)的权限相同。
Aniket Thakur 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.