【问题标题】:Differences between Intent and PendingIntentIntent 和 PendingIntent 的区别
【发布时间】:2014-08-07 01:52:48
【问题描述】:

我阅读了一些文章。所有人似乎都在做同样的事情,我想知道启动以下服务有什么区别:

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;

【问题讨论】:

  • 没有区别。是什么让你认为会有?在第一种情况下,您是“现在”启动它,而在第二种情况下,您只是将其安排为以后的时间/数据。

标签: android android-service


【解决方案1】:

IntentPendingIntent 之间还有另一个主要区别,最好注意这一点,否则您的应用设计可能会变得易受攻击。这个问题在Android Nesting Intents 文章中有很好的描述。

请注意,PendingIntent.send() 方法不接受 Context 实例,而是使用在意图创建期间提供的上下文。它允许第三方组件在意图创建者的上下文中执行与未决意图相关联的操作。

让我们想象一个第三方服务执行某些工作,然后启动您的应用指定的活动作为意图。如果 callback 活动作为基本的Intent 提供,则服务只能使用自己的上下文启动它,这样的设计有两个缺点:

  • 它强制回调活动被定义为exported,因此它可以使用第三方上下文启动。因此,Activity 不仅可以由它所针对的服务启动,还可以由设备上安装的任何其他应用启动。
  • 第三方服务应用定义的任何活动都可以用作回调活动,即使是非导出活动,因为它是使用第三方上下文启动的。

这两个问题都可以通过将 callback 活动指定为 PendingIntent 来轻松解决。

【讨论】:

  • 我认为exported这个字符是最重要的
  • 这是我认为最好的答案,引用的文章是无价的。
【解决方案2】:

另一个简单的区别:

  • 应用被终止后,正常意图将立即消失。

  • 未决意图永远不会消失。只要警报服务、位置服务或任何其他服务需要,它们就会一直存在。

【讨论】:

    【解决方案3】:

    意图

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

    intent 本身,一个 Intent 对象,是一个被动的数据结构。它包含要执行的操作的抽象描述。

    例如:假设您有一个 Activity 需要启动电子邮件客户端并发送电子邮件。为此,您的 Activity 会向 Android Intent Resolver 发送带有操作 ACTION_SEND 的 Intent 以及相应的选择器:

    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 或其他 3rd 方应用程序)的令牌,它允许外部应用程序使用您的应用程序的权限执行一段预定义的代码。

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

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

    来源:Android IntentsAndroid Pending Intents

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        功能上没有区别。

        PendingIntent 的含义是,你可以将它处理给其他应用程序,以后可以像其他应用程序一样使用它。以下是来自documentation的相关解释:

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

        PendingIntent 本身只是对由以下人员维护的令牌的引用 描述用于检索它的原始数据的系统。

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

        【讨论】:

        • 说功能上没有区别是不正确的。如果两者的功能相同,那么为什么将两个放在第一位呢?最重要的区别在于 PendingIntent 由远程组件(如 NotificationManager)执行,其权限与移交它的组件(创建通知的组件)相同。
        【解决方案6】:

        通过 AlarmManager 定期启动服务

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

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

        更新:

        因此两者之间没有实际区别。 但是根据您是否要确保服务的执行,您可以决定使用什么,因为对于 former 没有保证,对于 later 它是.

        更多信息请访问AndroidServices

        【讨论】:

        • 这实际上并没有回答 OP 的问题,即直接启动服务和启动带有警报的服务之间的“有什么区别”。此外,OP 可能已经看到您链接到的文章,因为文章中的代码与 OP 发布的代码几乎相同。
        • 您的意思是从 AlarmManager 启动服务比从 Activity 启动服务更安全,更不容易被杀死?我认为这是错误的。你能解释一下吗。 @VedPrakash。此外,我认为您在创建启动服务的意图时传递的上下文更重要。使用应用程序的上下文(getApplicationContext())而不是活动的上下文(this)应该更安全。
        • @Eu.Dr.我建议您使用每次 X 时都会触发的警报管理器...执行任务.. 为什么?因为如果您使用服务,它可能会在某个时候关闭,并且您最终可能会在某个时间跳过一些更新(未知)。对于上下文疑问,切勿使用 getApplicationContext() 或在严格要求时使用它,只需阅读 - when-to-call-activity-context-or-application-context (stackoverflow.com/questions/7298731/…)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-21
        • 1970-01-01
        • 2014-07-06
        • 1970-01-01
        • 2011-02-22
        • 2013-08-04
        相关资源
        最近更新 更多