【问题标题】:Android Application class being called twiceAndroid应用程序类被调用两次
【发布时间】:2010-10-16 00:22:37
【问题描述】:

在我的 Android 应用程序中,我重载了 Application 类,并更新了清单中的标签。此应用程序还创建了一个 Android 服务。 我在我的 Application 类的 onCreate 中放了一些日志,我看到它被调用了两次。 第一次是我的应用程序启动时(这是预期的),然后通常是在创建服务之后。 该日志还显示正在创建应用程序的第二个实例。 (我打印“this”值,它们是不同的)。

我认为应用程序将被创建为单例。 这是因为我创建了一个服务吗?

【问题讨论】:

    标签: android


    【解决方案1】:

    是的,如果您使用了 android:process,那么您就让它在一个单独的进程中运行,因此当服务启动时,会为其启动一个新进程,因此需要为该进程创建一个新的 Application 对象。

    但是还有一个更根本的问题——应用程序对象启动它的一项服务是不正确的。不要将应用程序与您对另一个操作系统中的“应用程序”的看法相混淆,这一点很重要。 Application 对象不驱动应用程序。它只是该过程中应用程序的全局状态。事实上,Application 对象完全是多余的——您永远不需要一个来编写 Android 应用程序。一般来说,我实际上建议人们不要使用它。它比其他任何事情都更容易引起麻烦。

    换一种说法:真正定义应用程序的是它的活动、服务、接收者和提供者标签的集合。这些就是“发射”的东西。所有的应用程序都是作为初始化应用程序进程的一部分而创建的。它没有自己的生命周期,它只是为应用程序中的其他真实组件提供服务。

    所以在设计你的应用程序时忽略应用程序;它将减少混乱。 (取而代之的是,我更喜欢对这种状态使用全局单例。)

    同样作为一般规则,我建议不要使用 android:process。它肯定有一些用途,但绝大多数时候它是不需要的,它只会让应用程序使用更多的 RAM,效率更低,更难编写(因为你不能在单个进程中利用全局变量) .如果您到达一个实际上有充分理由使用 android:process 的地方,那么您应该很清楚。

    【讨论】:

    • +1,虽然我想知道当每个进程需要初始化一次时,是否有比 MyApplication.onCreate() 更好的选择。例如,我还能在哪里可靠地为未捕获的异常注册处理程序?当我有活动和服务时,onCreate() 有效。
    【解决方案2】:

    Service 不应该真的被认为是一个 Activity,如果你这样想,你以后肯定会遇到问题。服务和活动可以属于同一个应用程序,如果您在 AndroidManifest.xml 中以这种方式定义它们,但它们的行为不同并且具有不同的生命周期。如果您希望您的服务在不同的进程中,那么您在<service> 部分中设置android:process="string" 以赋予它与您的应用程序名称不同的名称。当全局变量在一个单独的进程中时,您将无法访问它,您应该通过 Intents 与您的服务进行通信。如果您的服务更复杂,您可能希望考虑通过 AIDL 使其可远程调用。如果您想要一个单例活动,则将该活动的launchMode 设置为singleInstancesingleTasksingleInstance 表示它将是此 Activity 在其任务堆栈中的第一个也是唯一一个实例,并且不会为任何新 Intent 创建新实例。由于它是该 Activity 的唯一实例,因此它将始终位于任务堆栈的顶部,并且始终处于处理指向该 Activity 的新 Intent 的位置。如果 Activity 被声明为singleTask,它也将是一个单例,但可能在同一个任务堆栈中还有其他活动,甚至可能在其上方的任务堆栈顶部有活动。这是一个需要注意的重要区别。记住这一点:在任务堆栈顶部 NOT 的单例活动无法处理新的 Intent,并且 Intent 将被丢弃。如果您希望您的 Activity 始终能够处理为其指定的所有新 Intent,那么您很可能希望使用 singleInstance

    【讨论】:

    • 也不要将任务堆栈与屏幕上可见的内容混淆。我只是想在这里说清楚。位于任务堆栈的顶部并不意味着它在屏幕上可见。因此,作为其任务堆栈中唯一 Activity 的单例 Activity,它可能在另一个 Activity 后面(在不同的任务中)的后台仍然能够处理 Intent(并且这样做会进入前台)
    【解决方案3】:

    问题是服务也是一个组件,有自己的生命周期,只是它没有用户界面。 您应该查看developer application fundamentals 的替代方案。

    【讨论】:

    • 看来问题可能与我使用 android:process 标签在清单中声明我的服务有关。这有意义吗?
    • 是的。我刚刚检查了相同的信息来源,这也是我所理解的。不过我没有测试。
    • 您的信息来源是什么?我很想知道如何处理这种情况。让服务创建自己的进程并不少见,并且应用程序类应该是可以共享全局对象的“单例”。
    • android.app.Serviceandroid.app.Activity。你从哪里知道服务是一个活动?它们位于完全不同的包中,您引用的文档清楚地表明它们的用途完全不同。 “is-a”关系通常意味着某种形式的继承或“扩展”关系。我认为这可能会给阅读本文的人带来令人困惑的信息,但那只是我自己。
    • 不用担心,感谢您更新您的答案。 :) 你说得对,它们在概念上是相关的,如果不是继承关系的话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多