13

我有一个应用程序,入口点是“登录/启动” Activity,我需要从服务器预加载新数据。这SplashActivity被声明为:

<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

AndroidManifest.xmlApplicationMainActivity.

我期待,在我Application被操作系统或用户(使用强制停止)停止后,然后由用户重新启动,我的应用程序的入口点将SplashActivity再次出现,系统会跳过SplashActivity并显示MainActivity.

问题:这是预期的行为吗?如果整个过程都停止了,我的应用程序不应该开始SplashActivity吗?这可以实现吗?

4

2 回答 2

28

实际上,这个问题及其一些答案解决了几个问题:


要回答您最初的问题,“是的,这是预期的行为”。

Android 将每个 Activity 视为一个独立的自包含实体。Android 会记住任务堆栈中的活动状态,并且它可以随时终止您的进程(其中包含您的所有活动),因为它“知道”它总是可以在需要时重建您的活动。当然,当您有一个复杂的应用程序,其中活动之间存在依赖关系和/或您有存储在Application类(或类似的静态/单一位置)中的全局数据时,这个概念就会失效。

当 Android 杀死你的进程时,它会记住任务中最顶层的活动,当用户返回任务时,它会重新创建进程,然后重新创建任务中最顶层的活动。在你的情况下,MainActivity.

例如,如果您的任务堆栈如下所示:

StartActivity -> ActivityB -> ActivityC -> ActivityD

并且您的任务进入后台并且Android会终止该进程,当用户返回任务时,只会ActivityD重新创建。完成后,Android将ActivityD重新创建ActivityC. 一旦ActivityC完成,Android 将重新创建ActivityB等。简而言之,当用户恢复任务时,不会重新创建完整的堆栈。

没有清单设置或意图标志的组合可以让您获得所需的行为。如果 Android 提供类似的东西会很好,但目前它没有。


您可以通过在应用程序派生类(或任何其他类)中使用静态(类)布尔变量来确定您的进程是否已重新启动。当进程重新启动时,此变量将始终具有该值false,然后您可以从任何地方检查变量的状态,并在必要时重新初始化(重新加载数据)。然后将变量设置为true. true即使您的所有活动都完成,它也会一直保留到进程被终止并重新创建。这样,您可以仅在需要时进行初始化。

您也可以将其用作从SplashScreen. 所以在你的所有活动中onCreate(),你可以检查这个布尔变量的状态,如果应用程序已经重新启动,你可以简单地重定向到SplashScreen这样的:

Intent intent = new Intent(this, SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

这将完成任务中的所有活动并在任务SplashScreen的根目录重新启动。


接下来,如果您想防止每次用户返回应用程序时都必须下载数据(当它在后台并随后被 AndroidOS 杀死时),您应该将下载的数据存储在私有缓存区域并使用它当应用程序重新启动时。如果您的进程被终止并重新启动,这可以防止必须重复下载数据。


处理此问题的另一种方法是将您的数据加载到服务中。如果您Service的进程正在运行,那么 Android 就不太可能杀死您的进程。您只需要确保Service在用户完成您的应用程序时关闭您的应用程序。


我意识到这个答案是冗长的。希望你能从中得到一些东西。

于 2012-06-28T16:34:29.377 回答
0

可以这样做:

1. SplashActivity每次都会开始毫无疑问。

2.下载数据并保存检查(布尔值),表明加载已完成。您可以使用SharedPreferences

3.下次检查情况并MainActivity立即开始。

于 2012-06-28T10:57:35.953 回答